后置处理器的调用时机

BeanPostProcessor是spring提供的接口,它有两个方法——postProcessBeforeInitialization、postProcessAfterInitialization。关于这两个方法的调用时机,可以参考spring源码注释。

    /**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
} /**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

从源码注释中可以看出,postProcessBeforeInitialization方法会在bean实例化和属性设置之后,自定义初始化方法(参考https://www.cnblogs.com/dubhlinn/p/10664402.html提到的3种方式)之前被调用,而postProcessAfterInitialization方法会在自定义初始化方法之后被调用。当容器中存在多个BeanPostProcessor的实现类时,会按照它们在容器中注册的顺序执行。对于自定义BeanPostProcessor实现类,还可以让其实现Ordered接口自定义排序。

后置处理器的注册方式

在ApplicationContext容器中,只需要按普通的bean注册即可;

但是在BeanFactory容器中,需要显示的调用addBeanPostProcessor()方法才能注册。

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered; /**
* 自定义后置处理器
* 用于在bean的初始化前后进行扩展
* 这里的初始化,指的是初始化阶段调用的方法,
* 例如@Bean注解的initMethod、spring提供的InitializingBean接口、jsr-250提供的@PostConstruct接口
* 当容器中存在多个后置处理器时,默认会按照其在容器中注册的顺序执行
* 对于自定义后置处理器,也可以通过实现Ordered接口来自定义其执行顺序,数字越大优先级越低
*/
public class AppleBeanPostProcessor implements BeanPostProcessor, Ordered { /**
* 在初始化前执行的扩展逻辑
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("apple".equals(beanName)) {
System.out.println("创建了苹果对象...");
}
return bean;
} /**
* 在初始化后执行的扩展逻辑
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("apple".equals(beanName)) {
System.out.println("苹果对象初始化完成...");
}
return bean;
} @Override
public int getOrder() {
return 3;
}
}
/**
* 用注册普通bean的方式注册自定义后置处理器
*/
@Configuration
@Import(value = {AppleBeanPostProcessor.class})
public class LifeBeanConfig2 {
}

后置处理器的作用

简单的说,后置处理器用于bean对象初始化前后进行逻辑增强。spring提供了BeanPostProcessor的很多实现类,例如AutowiredAnnotationBeanPostProcessor用于@Autowired注解的实现,AnnotationAwareAspectJAutoProxyCreator用于SpringAOP的动态代理等等。除此之外,我们还可以自定义BeanPostProcessor的实现类,在其中写入需要的逻辑。下面以AnnotationAwareAspectJAutoProxyCreator为例,说明后置处理器是怎样工作的。我们都知道springAOP的实现原理是动态代理,最终放入容器的是代理类的对象,而不是bean本身的对象,那么spring是什么时候做到这一步的?就是在AnnotationAwareAspectJAutoProxyCreator后置处理器的postProcessAfterInitialization方法,即bean对象初始化完成之后,后置处理器会判断该bean是否注册了切面,如果是,则生成代理对象注入容器

    /**
* Create a proxy with the configured interceptors if the bean is
* identified as one to proxy by the subclass.
* @see #getAdvicesAndAdvisorsForBean
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

spring的生命周期

所谓spring的生命周期,是指一个bean对象在容器中从创建到销毁的过程,大致会经历如下过程:

1. 执行bean的构造方法,生成bean对象

2. 执行bean的set方法,注入属性

3. 如果容器中存在BeanPostProcessor的实现类,则执行它们的postProcessorBeforeInitialization方法

4. 如果bean实现了InitializingBean接口,则执行afterPropertiesSet方法

5. 如果<bean>标签或@Bean注解中定义了init-method/initMethod,则执行其引用的方法

6. 如果容器中存在BeanPostProcessor的实现类,则执行它们的postProcessorAfterInitialization方法

7. 关闭容器时,如果bean实现了DisposableBean接口,则执行destroy方法

8. 关闭容器时,如果<bean>标签或@Bean注解中定义了destroy-method/destroyMethod,则执行其引用的方法

最新文章

  1. 13、ASP.NET MVC入门到精通——MVC请求管道
  2. java lambda小纪
  3. 夺命雷公狗---DEDECMS----7dedecms目录结构
  4. CSS实现三角形图标的原理《转载》
  5. jmeter 使用jmeter 录制web脚本
  6. 使用Aspose.Cells利用模板导出Excel(C#)
  7. maven常用命令介绍
  8. maven入门(8)maven的依赖管理
  9. android Material Design详解
  10. VirtualBox报错:不能为虚拟电脑XXX打开一个新任务
  11. GoLang structTag说明
  12. .net core api +swagger(一个简单的入门demo 使用codefirst+mysql)
  13. Android视图动画集合AndoridViewAnimations
  14. day_6.16网络编程
  15. Python模块和类.md
  16. C# ListView用法
  17. org.springframework.dao.InvalidDataAccessApiUsageException
  18. UVA 11881 - Internal Rate of Return - [二分]
  19. typeof
  20. learning docker steps(5) ----- docker stack 初次体验

热门文章

  1. 输入某年某月某日,判断这一天是这一年的第几天?(可以用 Python 标准 库)
  2. Educational Codeforces Round 72 (Rated for Div. 2) Solution
  3. MinGW的安装
  4. nginx启动报错
  5. GridView做加
  6. SSM框架返回json数据
  7. msdn帮助,离线下载
  8. ST7735和ST7789驱动
  9. ARP详解和ARP攻击
  10. 10年前文章_使用opkg 管理软件更新