Spring Framework 源码学习笔记(四)

2022-08-19 15:59:47 浏览数 (1)

Chapter 04 - BeanPostProcessor

Section 01 - 简单Debug Bean创建和初始化调用过程

先大概过一下单例Bean创建和初始化过程,调用了哪些方法?

alt command b进入AnnotationConfigApplication类中,调用过程为:

refresh() --> finishBeanFactoryInitialization(beanFactory) --> beanFactory.preInstantiateSingletons() --> getBean(beanName) --> doGetBean(name, null, null, false) --> createBean(beanName, mbd, args) --> doCreateBean(beanName, mbdToUse, args)

源码中在这里doCreateBean()方法中分别创建Bean和初始化Bean

Bean创建过程执行的方法:

doCreateBean(beanName, mbdToUse, args) --> createBeanInstance() --> instantiateBean() --> getInstantiationStrategy().instantiate() --> BeanUtils.instantiateClass() --> newInstance()

这里调用newInstance()方法成功创建了业务Bean Item

再来看doCreateBean()方法中Bean初始化过程的前置方法初始化方法后置方法调用

Debug到这个位置可看出Address Bean在执行初始化方法前要经过这个7个BeanPostProcessor的处理,其中CustBeanPostProcessor是自定义的Bean,该类实现了BeanPostProcessor的前置和后置处理器,返回Bean并打印Bean的name

继续Debug可以看出这里会首先经过ApplicationContextAwareBeanPostProcessor的处理

继续往下循环到自定义的BeanPostProcessor,这里点击step into 进入到postProcessBeforeInitialization方法中

如下图可以看出这里调用了自定义的postProcessBeforeInitialization,输出beanName等信息

step over再往下一步,查看控制台信息既可以看到前置处理器方法被调用

Section 02 - BeanPostProcessor

The BeanPostProcessor interface defines callback methods that you can implement to provide your own (or override the container’s default) instantiation logic, dependency resolution logic, and so forth. If you want to implement some custom logic after the Spring container finishes instantiating, configuring, and initializing a bean, you can plug in one or more custom BeanPostProcessor implementations.   BeanPostProcessor接口可以定义回调方法,可以实现这些方法来提供自己的(或覆盖容器的默认)实例化逻辑、依赖项解析逻辑等。如果希望在Spring容器完成bean的实例化、配置和初始化后实现一些自定义逻辑,可以插入一个或多个自定义BeanPostProcessor实现, Spring的AutowiredNotationBeanPostProcessor就是一个例子 — BeanPostProcessor实现,自定义的例子可以参考CustBeanPostProcessor,但是要注意实现前置和后置处理器方法时一定不能返回null

BeanPostProcessor 与 Spring AOP

BeanPostProcessor instances and AOP auto-proxying Classes that implement the BeanPostProcessor interface are special and are treated differently by the container. All BeanPostProcessor instances and beans that they directly reference are instantiated on startup, as part of the special startup phase of the ApplicationContext. Next, all BeanPostProcessor instances are registered in a sorted fashion and applied to all further beans in the container. Because AOP auto-proxying is implemented as a BeanPostProcessor itself, neither BeanPostProcessor instances nor the beans they directly reference are eligible for auto-proxying and, thus, do not have aspects woven into them. For any such bean, you should see an informational log message: Bean someBean is not eligible for getting processed by all BeanPostProcessor interfaces (for example: not eligible for auto-proxying). If you have beans wired into your BeanPostProcessor by using autowiring or @Resource (which may fall back to autowiring), Spring might access unexpected beans when searching for type-matching dependency candidates and, therefore, make them ineligible for auto-proxying or other kinds of bean post-processing. For example, if you have a dependency annotated with @Resource where the field or setter name does not directly correspond to the declared name of a bean and no name attribute is used, Spring accesses other beans for matching them by type.

  实现BeanPostProcessor接口的类不同于普通的业务类的Bean,会被容器特殊对待,它们直接引用的所有BeanPostProcessor实例和bean都是在启动时实例化的,作为ApplicationContext的特殊启动阶段的一部分。在Bean创建完成后,以排序的方式注册所有BeanPostProcessor实例,并应用于容器中的所有的Bean。AOP就是实现了BeanPostProcessor。

0 人点赞