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 customBeanPostProcessor
implementations.   BeanPostProcessor接口可以定义回调方法,可以实现这些方法来提供自己的(或覆盖容器的默认)实例化逻辑、依赖项解析逻辑等。如果希望在Spring容器完成bean的实例化、配置和初始化后实现一些自定义逻辑,可以插入一个或多个自定义BeanPostProcessor实现, Spring的AutowiredNotationBeanPostProcessor就是一个例子 — BeanPostProcessor实现,自定义的例子可以参考CustBeanPostProcessor,但是要注意实现前置和后置处理器方法时一定不能返回null
BeanPostProcessor 与 Spring AOP
BeanPostProcessor
instances and AOP auto-proxying Classes that implement theBeanPostProcessor
interface are special and are treated differently by the container. AllBeanPostProcessor
instances and beans that they directly reference are instantiated on startup, as part of the special startup phase of theApplicationContext
. Next, allBeanPostProcessor
instances are registered in a sorted fashion and applied to all further beans in the container. Because AOP auto-proxying is implemented as aBeanPostProcessor
itself, neitherBeanPostProcessor
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 yourBeanPostProcessor
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。