To load the value of a property file (properties) into a Java class using the Java annotation attribute

Source: Internet
Author: User
Tags config integer

Before that I was writing a propertyutil class to load the configuration file, and then get the value out of the key by using the Fetch method.

Spring provides a propertyplaceholderconfigurer class that can read the configuration file and then inject it into the JavaBean in the spring configuration file through ${hibernate.dialect}. One bad thing about it is that it's not convenient to take it in the code.

And then in contact with the Java Annotation Special annotation technology, feel this thing is very good, hibernate mapping, WebService can be done through annotations, a lot of convenience, and then think can be through the Java Annotation Attributes load property file (properties) Value into the Java class?

In fact, the previous write in spring JavaBean initialization order is to write this now, to achieve this function, the general plan is as follows:

1. Define an annotation class

2. Write the annotation on the property set method of the JavaBean that needs to load the attribute, the annotation parameter is the key

3. When spring starts, read the properties file and assign the value to JavaBean

The initialization order we wrote in spring in JavaBean mentioned that if a JavaBean implements the Beanpostprocessor interface, The other bean is then initialized to be processed by the bean. So we can write a JavaBean implementation Beanpostprocessor interface, this bean has an attribute that points to the property file path, and reads the property file contents when the Bean initializes, The Postprocessbeforeinitialization method is then assigned to the bean that has the annotation written in it. Such a realization thought seems very natural, is not very good, Spring is loading the property file by propertyplaceholderconfigurer such classes, and we have written another class, which is not uniform, Two is not enough may result in multiple property files. The solution is to extend the Propertyplaceholderconfigurer class. Write a class to inherit the Propertyplaceholderconfigurer class. And then in Propertyplaceholderconfigu RER after initialization completes, gets the contents of the loaded property file, The class attribute of the annotation is assigned to the postprocessbeforeinitialization. So how do you know when propertyplaceholderconfigurer loading is complete? Based on the initialization order of JavaBean in spring, we know that a JavaBean if the Initializingbean interface is implemented, then the spring container invokes the Afterpropertiesset method after the bean is initialized. Now I write a class to inherit the Propertyplaceholderconfigurer class, implement Beanpostprocessor, Initializingbean this two interface then the problem just mentioned can be solved, the following is the implementation code

package com.test.annotation;


import Java.lang.reflect.Method;


import org.springframework.beans.BeansException;


Import Org.springframework.beans.factory.InitializingBean;


import Org.springframework.beans.factory.config.BeanPostProcessor;


import Org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;


import org.springframework.util.ReflectionUtils;


public class Annotationbeanpostprocessor extends Propertyplaceholderconfigurer implements Beanpostprocessor, Initializingbean {


Private java.util.Properties Pros;


@Override


public Object Postprocessafterinitialization (object bean, String beanname)


throws Beansexception {


//TODO auto-generated method stub


return bean;


   }


@Override


public Object Postprocessbeforeinitialization (object bean, String beanname)


throws Beansexception {


if (Bean.getclass (). Getannotation (Property.class)!=null) {


method[] methods = Bean.getclass (). Getdeclaredmethods ();


for (method Method:methods) {


Property P = method.getannotation (Property.class);


if (p!=null) {


//Here for parameter type conversion


Object Para=pros.getproperty (P.name ());


if ((Method.getparametertypes () [0]). GetName (). Equals ("Java.lang.Integer")) {


para= New Integer (para.tostring ());


           }


Reflectionutils.invokemethod (method, Bean, New Object[]{para});


         }


       }


     }


return bean;


   }


@Override


public void Afterpropertiesset () throws Exception {


pros = mergeproperties ();


}


}


package com.test.annotation;


import java.lang.annotation.Retention;


import Java.lang.annotation.RetentionPolicy;


import Java.lang.annotation.Target;


import Java.lang.annotation.ElementType;


@Retention (retentionpolicy.runtime)


@Target ({elementtype.type, elementtype.method})


Public @interface Property {


String name () default "";


}


package com.test;


import Com.test.annotation.Property;


@Property


public class Bean {


private String name;


private Integer age;


private String address;


public String GetName () {


return name;


   }


public void SetName (String name) {


this.name = name;


   }


public String getaddress () {


return address;


   }


@Property (name= "com.test.Bean.address")


public void setaddress (String address) {


this.address = address;


   }


public Integer Getage () {


return age;


   }


@Property (name= "Com.test.Bean.age")


public void Setage (Integer age) {


this.age = age;


   }


}


package com.test;


import Com.test.annotation.Property;


@Property


public class JavaBean {


private String name;


private String address;


public String GetName () {


return name;


   }


@Property (name= "Com.test.JavaBean.name")


public void SetName (String name) {


this.name = name;


   }


public String getaddress () {


return address;


   }


public void setaddress (String address) {


this.address = address;


   }


}


package com.test;


import Org.springframework.context.ApplicationContext;


import Org.springframework.context.support.ClassPathXmlApplicationContext;


public class Test {


   /**


* @param args


   */


public static void Main (string[] args) {


ApplicationContext context =


new Classpathxmlapplicationcontext ("Spring.xml");


System.out.println ("Load configuration file End");


System.out.println ("--------------------------------------------");


JavaBean javabean= (JavaBean) Context.getbean ("JavaBean");


System.out.println (Javabean.getname ());


System.out.println (Javabean.getaddress ());


System.out.println ("--------------------------------------------");


Bean bean= (Bean) Context.getbean ("Bean");


System.out.println (Bean.getname ());


System.out.println (Bean.getaddress ());


System.out.println (Bean.getage ());


System.out.println ("--------------------------------------------");


   }


}


<?xml version= "1.0" encoding= UTF-8 "?>"


<! DOCTYPE beans Public "-//spring//dtd bean//en" "Http://www.springframework.org/dtd/spring-beans.dtd" >


<beans>


<bean id=


Attribute-value> "Propertyconfigurer" class= "Com.test.annotation.AnnotationBeanPostProcessor" >


<property name= "Locations" >


<list>


<value>classpath*:system.properties</value>


</list>


</property>


</bean>


<bean id= "JavaBean" class= "Com.test.JavaBean" >


<property name= "Address" value= "${com.test.javabean.address}" ></property>


</bean>


<bean id= "Bean" class= "Com.test.Bean" >


<property name= "name" value= "${com.test.bean.name}" ></property>


</bean>


</beans>

PS: The reason to inherit the Propertyplaceholderconfigurer class, there is another reason is that the original through ${} injection of the value of the way can also be used

Beanpostprocessor has two methods, why write in Postprocessbeforeinitialization, not postprocessafterinitialization inside, The reason is that the Postprocessbeforeinitialization method is executed before the Bean's Init method, and the properties of the class may be used inside the Init method, so the value must be assigned before the Init method executes.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.