我们通过上一节的学习,可以知道,Autowired注解是哪一个后置处理器解析的。我们现在来分析AutowiredAnnotationBeanPostProcessor这个后置处理器到底是如何解析Autowired。首先我们做下准备工作。实现类我们仍然用上一节用的LifeCycleBean这个类,启动入口仍然是boot,不过我们这里用BeanFactory的实现类当容器。目前容器中没有任何的bean后置处理器。


首先我们先手动注册一个A类,该类是需要被注入的。 然后我们直接手动new一个AutowiredAnnotationBeanPostProcessor后置处理器。调用setBeanFactroy方法,作用是和beanfactory建立关系,当依赖注入时,就会去beanfactroy中找对应的bean完成注入。当我们new出一个LifeCycleBean的实例时,此时仅仅只有构造方法执行,其他的没有执行,原因看前面一章。然后我们调用postProcessProperties方法,该方法的第一个参数,是让我们指定注入的参数,如果我们传入该参数,那么就不会去根据原有的方法进行查找并注入。所以我们直接传null,第二个参数是我们要注入的bean,毋庸置疑,我们要向cycleBean中依赖注入。第三个就是bean的名字,这个可有可无,意义不大,也可以不用写。 程序运行结果可以看出,当调用此方法后,autowired注入就成功了,方法也执行了。由此看出,postProcessProperties这个方法就是关键。

我们可以追进看看源码,第一行,findAutowiringMetadata方法,翻译过来就是找到Autowiring的元数据。简单来说就是,找到bean中有哪些方法或者属性上有@Autowired注解。并封装到InjectionMetadata返回。看到这里是不是很想看看返回的metadata中到底有哪些东西以及怎么封装的。没错,我也很想看。这里两种方法,第一种就是很简单的打断点,debug,这种方法太简单就不演示了,我们就演示第二种,通过反射执行findAutowiringMetadata方法,得到返回结果。为什么用反射呢,其实很简单,因为是个私有方法,你访问不到呀,只能反射。


我们通过反射拿到该返回结果,但由于并没有重写tostring,所以我们依然需要断点,我们就当复习下反射了。我们可以看到,不仅找到了对应的方法和属性,还把他们都放到了injectElements集合当中,并且方法和属性,用不同的类型封装存储。这里说一下,为什么多出来个a字段,是我为了测试属性和方法都有效才加的,所以不用太疑惑。

当得到metadata数据,就可以执行下一行代码了,就是inject,翻译过来就是注入,这就是真正注入的方法了。inject方法内部使用了反射来进行依赖注入。由于该方法源码过于复杂,就不继续追。

我们可以自己写个大概的反射流程来模拟inject内部是如何查找到对象的。这是属性的自动注入,找对应的bean。前面我们已经得到了metadata了,所以我们可以根据反射得到对应的属性,这时我们会将其封装成一个DependencyDescription对象,第一个参数就是字段,第二个是是否必须要在beanfactory容器中找到对应的对象。false代表就是不是必须的。 然后我们调用工厂的doResolveDependency方法进行查找,返回的就是查找到的对象。此时对象找到,注入就轻松了。方法也是大概一致的,不多赘述了。

本文使用 文章同步助手 同步
