Spring IOC学习心得之BeanPostProcessor,BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口是如何起作用的
来源:互联网 发布:mysql分页是什么 编辑:程序博客网 时间:2024/05/21 06:17
1. 首先说下BeanPostProcessor接口中的两个方法,如下:
package org.springframework.beans.factory.config;import org.springframework.beans.BeansException;public interface BeanPostProcessor { //Bean初始化的前置处理器Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;//Bean初始化的后置处理器Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;}应用中自定义的Bean,可以实现这个接口,并覆盖这两个方法来控制Bean的初始化过程,即在Bean的初始化之前做一件事,即调用postProcessBeforeInitialization方法,也可以在Bean的初始化之后做一件事,即调用postProcessAfterInitialization方法。那么这两个方法究竟是如何被Spring调用的呢?
2. 在Bean的初始化过程中,会调用initializeBean方法,该方法的源码如下:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {invokeAwareMethods(beanName, bean);return null;}}, getAccessControlContext());}else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {//执行BeanPostProcessor扩展点的PostProcessBeforeInitialization进行修改实例化BeanwrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//调用Bean的初始化方法,这个初始化方法是在BeanDefinition中通过定义init-method属性指定的//同时,如果Bean实现了InitializingBean接口,那么这个Bean的afterPropertiesSet实现也不会被调用invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {//执行BeanPostProcessor扩展点的PostProcessAfterInitialization进行修改实例化BeanwrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}
3. BeanPostProcessor起作用的方式
先说下invokeInitMethods方法,这个是真正的Bean的初始化方法,我们可以看到在该方法之前有一个方法applyBeanPostProcessorsBeforeInitialization,该方法实现Bean初始化的前置处理,可以看下该方法的源码:
@Overridepublic Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessBeforeInitialization(result, beanName);if (result == null) {return result;}}return result;}
这个方法中会通过getBeanPostProcessors方法去获取Bean所实现的所有的BeanPostProcessor接口,并调用其postProcessBeforeInitialization方法来实现在Bean的初始化之前做一些预处理
在invokeInitMethods方法之后,有一个applyBeanPostProcessorsAfterInitialization方法,该方法实现Bean的初始化的后置处理,可以看下该方法的源码:
@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessAfterInitialization(result, beanName);if (result == null) {return result;}}return result;}
与前置处理类似,也是获取Bean实现的所有BeanPostProcessor接口,然后调用所有接口的postProcessAfterInitialization后置处理方法
4. BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口起作用的方式
大家注意到initializebean方法中有一个invokeAwareMethods方法,先看下这个方法的源码:
private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}
举例来说,当应用自定义的Bean实现了BeanNameAware接口,如下:
public class MyBean implements BeanNameAware { private String beanName; void setBeanName(String name) { this.beanName = name; }}
这样就可以获取到该Bean在Spring容器中的名字,原理就是上述invokeAwareMethods方法中,判断了如果bean实现了BeanNameAware接口,就会调用该Bean覆盖的BeanNameAware接口的setBeanName方法,这样MyBean中就获取到了该Bean在Spring容器中的名字。
BeanClassLoaderAware接口和BeanFactoryAware接口同理,可以分别获取Bean的类装载器和bean工厂
5. InitializeBean接口起作用的方式
最后来说下真正的初始化方法invokeInitMethods,该方法的源码如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isDebugEnabled()) {logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {try {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {@Overridepublic Object run() throws Exception {((InitializingBean) bean).afterPropertiesSet();return null;}}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {((InitializingBean) bean).afterPropertiesSet();//启动afterPropertiesSet,afterPropertiesSet是InitializingBean接口的方法}}if (mbd != null) {String initMethodName = mbd.getInitMethodName();//获取用户自定义的初始化方法if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {invokeCustomInitMethod(beanName, bean, mbd);//调用自定义的初始化方法}}
可以看到方法中判断了如果该Bean实现了InitializeBean接口,即bean instanceof InitializingBean == true,就会调用该Bean实现的Initializebean接口的afterPropertiesSet方法
6. 自定义的初始化方法起作用的方式
上述代码中有一个方法getInitMethodName,可以获取用户自定义的初始化方法,然后通过调用invokeCustomInitMethod方法来执行用户自定义的初始化方法
0 0
- Spring IOC学习心得之BeanPostProcessor,BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口是如何起作用的
- Spring的BeanNameAware和BeanFactoryAware接口
- Spring—BeanNameAware、BeanFactoryAware
- BeanNameAware接口和BeanFactoryAware接口
- BeanNameAware接口和BeanFactoryAware接口
- BeanNameAware接口和BeanFactoryAware接口
- BeanNameAware接口和BeanFactoryAware接口
- BeanNameAware接口和BeanFactoryAware接口
- BeanNameAware接口和BeanFactoryAware接口
- BeanNameAware接口和BeanFactoryAware接口
- spring之BeanFactoryAware接口
- spring之BeanFactoryAware接口
- 《Pro Spring》学习笔记之BeanNameAware和BeanFactoryAware
- Spring 源码梳理(六) BeanNameAware和BeanFactoryAware
- Spring之BeanPostProcessor接口
- PASSION之Spring-BeanPostProcessor接口
- 做一个合格的程序猿之浅析Spring IoC源码(九)了解BeanNameAware
- 有关Spirng ioc的BeanPostProcessor接口案例
- android音视频点/直播模块开发
- junit排序
- 多项式拟合
- 如何开始创建第一个基于Spring MVC的Controller
- 正则表达式30分钟入门
- Spring IOC学习心得之BeanPostProcessor,BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口是如何起作用的
- VS2013中,将Qt的GUI程序改为控制台程序
- OC 方法 继承 多态
- 微服务架构设计 第五步: 微服务的 User Stories 的拆分与澄清
- 平台,设备,驱动
- List、Map、Set三个接口,存取元素时,各有什么特点?
- 社工方法加载OLE对象,更改浏览器代理设置窃取信息
- 基础知识点
- 直播云服务技术详解