AutowiredAnnotationBeanPostProcessor详解

准备好BeanFactory,因为@Autowired需要在BeanFactory中找需要的Bean参数

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("bean2",new Bean2());
beanFactory.registerSingleton("bean1",new Bean1());
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());//@Value

new 一个后处理器对象,设置其Bean工厂属性

AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(beanFactory);

首先自己new一个对象,没有经过后处理器处理,打印结果

        Bean3 bean3 = new Bean3();
        System.out.println(bean3);

 

可见属性还没有赋值

 执行后处理器:

        processor.postProcessProperties(null,bean3,"bean3");//执行依赖注入,解析@Autowirde @Value
        System.out.println(bean3);

打印:

 

Bean3属性已经赋上值了 

 postProcessProperties()方法属于InstantiationAwareBeanPostProcessor接口定义的方法的,在之前自定义Bean处理器时使用过,可以在依赖注入的时候执行方法

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

        try {
            metadata.inject(bean, beanName, pvs);
            return pvs;
        } catch (BeanCreationException var6) {
            throw var6;
        } catch (Throwable var7) {
            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
        }
    }

 其中第一行执行findAutowiringMetadata()方法就是去分析Bean3类中,有哪些成员变量上有@Autowired和@Value 的信息,封装在返回结果metadata中

 由于方法是私有的,利用反射更好的观察运行过程

Method findAutowiringMetadata = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod("findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
findAutowiringMetadata.setAccessible(true);
InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadata.invoke(processor, "bean3", bean3, null);

用debug查看 metadata

 其中的InjectdElements封装着要注入的方法和属性

 

 调用metadata的inject方法,实现注入属性

metadata.inject(bean3,"bean3",null);

 加入${}解析器

beanFactory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);//解析${}

打印:

 如何根据类型找对象?

1.反射获取方法或变量

2.封装一个DependencyDescriptor对象

3.调用beanFactory.doResolveDependency()

//3.如何按类型找值
        Field bean1 = Bean3.class.getDeclaredField("bean1");
        //参数:1.传入要注入的字段 2.是否时必须的,false指找不到也不会报错
        DependencyDescriptor dd1 = new DependencyDescriptor(bean1, false);
        Object o = beanFactory.doResolveDependency(dd1, null, null, null);
        System.out.println(o);

 打印:

成功找到对象,之后可以通过反射设置其值

        bean1.setAccessible(true);
        bean1.set(bean3,o);
        System.out.println(bean3);

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值