1, 我们都知道@Value注解,非常好用。但是不知道他的原理, 今天我们来仿写一下, 看一看他具体是怎么实现的啊。
2, 这里我们主要用到的是BeanPostProcessor 这个后置处理器, 对bean的实体进行增强。
具体的实现
先创建自定义注解@Myvalue . 里面有value 的值 ,必填项。
在创建自己的自定义类实现BeanPostProcessor的方法。
在里面注入Environment , 从配置文件 拿到 value 的值, 当做key ,在去配置文件真正的值。
具体代码
代码语言:javascript复制@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Import(FeignRegister.class)
public @interface MyValue {
String value();
}
@Component
public class MyValueBeanPostProcess implements BeanPostProcessor {
@Autowired
private Environment environment;
// 要在创建bean 之前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 使用反射给类的属性赋值
Field[] declaredFields = bean.getClass().getDeclaredFields();
for (Field declaredField : declaredFields) {
MyValue annotation = declaredField.getAnnotation(MyValue.class);
if (null == annotation) {
continue;
}
// 去掉private 私有访问权限
declaredField.setAccessible(true);
try {
declaredField.set(bean,environment.resolvePlaceholders(annotation.value().replaceAll("/$", "")));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
@Service
public class Test2Service {
@MyValue(value = "${name}")
private String name;
}
properties 里面
name=dddddd
测试: