- 调用顺序:在Bean的初始化前后调用,分别对应了其中的两个方法
- Bean的后置处理器对应的接口是
BeanPostProcessor
,其中定义了两个方法,如下:public interface BeanPostProcessor{ /** * 在Bean初始化之前执行,即是在执行Bean的构造方法之后,在执行InitializingBean的afterPropertiesSet方法之前执行 */ ObjectpostProcessBeforeInitialization(Object bean, String beanName)throws BeansException; /** * 在Bean的初始化之后执行,即是在InitializingBean的afterPropertiesSet方法之后执行 */ ObjectpostProcessAfterInitialization(Object bean, String beanName)throws BeansException; }
使用场景
- 在Bean的初始化前后做一些自己的逻辑处理,比如为Bean设置一些额外的属性。
- 最典型的例子就是spring中的Aware接口的实现,都是利用
BeanPostProcessor
在Bean初始化之前进行调用set方法设置相应的属性【详情请看ApplicationContextAwareProcessor
源码】 -
@Autowired
的实现依赖注入也是使用的BeanPostProcessor的原理,详情请看AutowiredAnnotationBeanPostProcessor
的源码
- 最典型的例子就是spring中的Aware接口的实现,都是利用
自定义后置处理器
- 必备条件:
BeanPostProcessor
-
自定义一个User类,如下:
/** * 实现InitializingBean接口,定义初始化方法,在构造方法之后执行 */ @Component public class Userimplements Serializable,InitializingBean{ private String name; private Integer age; public User(){} public User(String name, Integer age){ System.out.println("执行构造方法"); this.name = name; this.age = age; } @Override public void afterPropertiesSet()throws Exception { System.out.println("执行初始化方法,在构造方法执行之后执行"); } }
-
自定义后置处理器,如下:
/** * 1、自定义的后置处理器,实现BeanPostProcessor * 2、必须注入到容器中才能执行 * 3、后置处理器是每一个Bean实例化前后都会调用的,并不能指定某一个 */ @Component public class FirstPostProcessorimplements BeanPostProcessor{ /** * 在Bean初始化之前执行,即是在执行Bean的构造方法之后,在执行InitializingBean的afterPropertiesSet方法之前执行 * @param bean bean的对象 * @param beanName bean的名字,即是在ioc容器中的id * @return 一定不能null * @throws BeansException */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException { //如果这个Bean是User类型 if (bean instanceof User){ System.out.println("在User的初始化方法【afterPropertiesSet】之前执行"); //改变属性的值 User user=(User)bean; user.setName("马云"); user.setAge(40); } return bean; } /** * 在Bean的初始化之后执行,即是在InitializingBean的afterPropertiesSet方法之后执行 * @param bean bean的对象 * @param beanName bean的名字,即是在ioc容器中的id * @return 一定不能null * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException { if (bean instanceof User){ System.out.println("在User的初始化方法【afterPropertiesSet】之后执行"); } return bean; } }
源码解析
- 最重要的就是后置处理器两个方法的执行顺序:
postProcessBeforeInitialization postProcessAfterInitialization
- 我们分别在自定义的后置处理器上打上断点,通过debug模式跟踪代码,程序的入口测试类如下:
- 使用
AnnotationConfigApplicationContext
启动容器public class FirstConfigTest{ public AnnotationConfigApplicationContext applicationContext; @Before public void initApplicationContext(){ applicationContext = new AnnotationConfigApplicationContext(FirstConfig.class); } }
- 使用
步骤
- 执行AnnotationConfigApplicationContext的构造方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses)
:-
register(annotatedClasses)
:注入指定的配置类FirstConfig
- 【
refresh()
:刷新容器,在这个执行结束之后会完成Bean的加载,详情见第2步】
-
- 进入
org.springframework.context.support.AbstractApplicationContext#refresh
方法:-
prepareRefresh();
:在刷新容器之前做一些准备工作,比如设置激活状态【activate】,设置启动时间【startupDate】 -
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
refreshBeanFactory() ConfigurableListableBeanFactory
-
prepareBeanFactory(beanFactory);
:对新创建的Bean工厂设置一些属性配置- 设置ClassLoader、表达式解析器、属性注入器
- 设置
ApplicationContextAwareProcessor
这个后置处理器到org.springframework.beans.factory.support.AbstractBeanFactory#beanPostProcessors
该成员变量中、去除一些不能自动注入的类【ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、EnvironmentAware】,因为这些Aware类型的类需要后续自定义实现的 - 向容器中注入一些能够自动注入的类【BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext】,这些类能够直接通过
@Autowired
直接注入使用 - 向容器中注入一些运行环境的Bean【
ConfigurableEnvironment
、systemProperties(Map<String,Object>
其中存放的是配置参数)】,这些Bean可以直接自动注入使用
-
invokeBeanFactoryPostProcessors(beanFactory)
:调用已经注册在容器中的BeanFactory后置处理器 -
registerBeanPostProcessors(beanFactory)
:向ioc容器中注册BeanFactoryProcessor -
initMessageSource()
:初始化MessageSource -
initApplicationEventMulticaster()
:初始化事件分发器 -
registerListeners()
:注册事件监听器,用来监听事件 - 【
finishBeanFactoryInitialization(beanFactory)
:初始化单例、非懒加载的Bean】,详情见步骤3 -
finishRefresh()
:发布事件
-
- 进入
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
:- 初始化类型转换类
- 初始化
LoadTimeWeaverAware
,用于方法织入 - 冻结BeanDefinition,表示后面的BeanDefinition不能再改变
- 【
beanFactory.preInstantiateSingletons()
:初始化Bean,详情请看第4步】
-
进入到
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
方法中,用于初始化Bean- 遍历所有的BeanNames,判断当前Bean是否是FactoryBean,如果不是运行getBean方法
-
进入到
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
,如下图所示,将是完整的逻辑,可以看出后置处理器为什么是在初始化之前和之后执行。
总结
- 从源码可以看出,最核心的执行就是在
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
的方法中,主要的代码逻辑是在初始化之前调用对应的before方法,在之后调用after方法。
以上所述就是小编给大家介绍的《Bean的后置处理器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- “统治”移动处理器市场的Arm为何明年Q1才发布AI处理器?
- AMD 7nm EPYC处理器亮相:性能提升一倍,世界最强X86处理器
- 36.Django内容处理器
- 处理器是如何调度进程的?
- JVM进阶 -- 浅谈注解处理器
- 俄致力打造国产神经网络处理器
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。