前面已经熟悉了自定义注解的简单例子,现在这个例子在实际应用中是比较有用的,用来将配置文件(*.properties)或者系统属性中的指定属性名称的值加载进来。此例是和Spring结合使用的,所以其他配置就略过了。
1、定义注解@Property
package com.kute.test.selfannotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解@Property
* 加载配置文件和相应的属性
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
public @interface Property {
//属性名称
String name() default "";
}
2、解析注解
package com.kute.test.selfannotation;
import java.lang.reflect.Method;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 PropertyParse extends PropertyPlaceholderConfigurer implements
BeanPostProcessor, InitializingBean {
private static Logger logger = LoggerFactory.getLogger(PropertyParse.class);
private Properties pros = null;
// 在spring容器实例化bean之后添加自己的逻辑
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
// 在spring容器实例化bean之前添加自己的逻辑
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) {
//获得对应名称的属性的值
Object para = pros.getProperty(p.name());
//方法参数类型名称
String parameterName = (method.getParameterTypes()[0]).getName();
if (parameterName.equals("java.lang.Integer")) {
para = new Integer(para.toString());
}else if (parameterName.equals(
"java.lang.Double")) {
para = new Long(para.toString());
}else if (parameterName.equals(
"java.lang.String")) {
para = para.toString();
}
logger.info("获得了指定名称的属性的值:" + para);
ReflectionUtils.invokeMethod(method, bean,
new Object[] { para });
}
}
}
return bean;
}
// 在初始化bean的时候执行该方法
public void afterPropertiesSet() throws Exception {
//此方法的作用是将配置的和系统属性加载进来
pros = mergeProperties();
}
}
3、应用注解
package com.kute.test.selfannotation;
import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Property
public class Teacher implements Serializable {
private static final long serialVersionUID = 7651360997972750779L;
private static Logger logger = LoggerFactory.getLogger(Teacher.class);
@Property(name = "third.kute.blog")
public void setValue(String value) {
logger.info("成功设String值:" + value);
}
@Property(name = "second.kute.age")
public void setValue(Integer value) {
logger.info("成功设Integer值:" + value);
}
@Property(name = "first.kute.name")
public void setValue(Double value) {
logger.info("成功设Double值:" + value);
}
}
4、配置文件(部分)(applicationContext.xml)
<!-- PropertyParse此bean是继承了PropertyPlaceholderConfigurer来加载配置文件 -->
<bean class="com.kute.test.selfannotation.PropertyParse">
<!-- 除了支持配置的*.properties外,还支持获取系统属性(System.getProperties() -->
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<!-- 资源找不到不抛出异常 -->
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath*:/first.properties</value>
<value>classpath*:/second.properties</value>
<value>classpath*:/third.properties</value>
</list>
</property>
</bean>
5、文件内容
first.properties
first.kute.name=36.0
first.kute.age=111111
first.kute.blog=http://blog.csdn.net/kutekute
second.properties
second.kute.name=37.0
second.kute.age=222222
second.kute.blog=http://blog.csdn.net/kutekute
third.properties
third.kute.name=38.0
third.kute.age=333333
third.kute.blog=http://blog.csdn.net/kutekute