仿写spring@Value 注解

2021-04-06 16:22:59 浏览数 (2)

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

测试:

0 人点赞