转载:http://blog.csdn.net/heyutao007/article/details/50326793

常用的设定方式有以下三种:
通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法;
通过 <bean> 元素的 init-method/destroy-method属性指定初始化之后 /销毁之前调用的操作方法;
在指定方法上加上@PostConstruct 或@PreDestroy注解来制定该方法是在初始化之后还是销毁之前调用。

  1. public class InitSequenceBean implements InitializingBean {
  2. public InitSequenceBean() {
  3. System.out.println("InitSequenceBean: constructor");
  4. }
  5. @PostConstruct
  6. public void postConstruct() {
  7. System.out.println("InitSequenceBean: postConstruct");
  8. }
  9. public void initMethod() {
  10. System.out.println("InitSequenceBean: init-method");
  11. }
  12. @Override
  13. public void afterPropertiesSet() throws Exception {
  14. System.out.println("InitSequenceBean: afterPropertiesSet");
  15. }
  16. }

并且在配置文件中添加如下Bean定义:

  1. <bean class="InitSequenceBean" init-method="initMethod"></bean>

输出结果:

InitSequenceBean: constructor
InitSequenceBean: postConstruct
InitSequenceBean: afterPropertiesSet
InitSequenceBean: init-method
 
通过上述输出结果,说明三种初始化的顺序是:
Constructor > @PostConstruct > InitializingBean > init-method

原因:
@PostConstruct注解后的方法在BeanPostProcessor前置处理器中就被执行了。我们知道BeanPostProcessor接口是一个回调的作用,spring容器的每个受管Bean在调用初始化方法之前,都会获得BeanPostProcessor接口实现类的一个回调。在BeanPostProcessor的方法中有一段逻辑就是会判断当前被回调的bean的方法中有没有被initAnnotationType/destroyAnnotationType注释,如果有,则添加到init/destroy队列中,后续一一执行。initAnnotationType/destroyAnnotationType注解就是@PostConstruct/@PreDestroy。所以@PostConstruct当然要先于InitializingBean和init-method执行了。

从图中,我们可以看到实例化Bean的过程中有以下几个节点:
1)设置属性值;
2)调用Bean中的BeanNameAware.setBeanName()方法,如果该Bean实现了BeanNameAware接口;
3)调用Bean中的BeanFactoryAware.setBeanFactory()方法,如果该Bean实现了BeanFactoryAware接口;
4)调用BeanPostProcessors.postProcessBeforeInitialization()方法;@PostConstruct注解后的方法就是在这里被执行的
5)调用Bean中的afterPropertiesSet方法,如果该Bean实现了InitializingBean接口;
6)调用Bean中的init-method,通常是在配置bean的时候指定了init-method,例如:<bean class="beanClass" init-method="init"></bean>
7)调用BeanPostProcessors.postProcessAfterInitialization()方法;
8)如果该Bean是单例的,则当容器销毁并且该Bean实现了DisposableBean接口的时候,调用destory方法;如果该Bean是prototype,则将准备好的Bean提交给调用者,后续不再管理该Bean的生命周期。

最新文章

  1. 虚拟化 - 每天5分钟玩转 OpenStack(2)
  2. C#:lock锁与订单号(或交易号)的生成
  3. 大前端学习笔记整理【七】HTTP协议以及http与https的区别
  4. C#如何实现一个简单的流程图设计器
  5. Linux Shell常用快捷键
  6. jQuery 控制表单和表格
  7. 根据不同的屏幕宽度引入不同的css文件
  8. Apache HttpClient
  9. AceAdmin In MVC之控件
  10. 【Vijos】【1164】曹冲养猪
  11. 对比MySQL,什么场景MongoDB更适用
  12. JSP内置对象(上)
  13. HDU 3416 Marriage Match IV
  14. Spring Boot 系列教程2-Data JPA
  15. Bagging和Boosting 概念及区别
  16. iOS 自动构建套件 - flow.ci + fir.im + Coding
  17. PhiloGL学习(1)——场景创建及方块欲露还羞出水面
  18. POJ 1236 Network of Schools (Tarjan)
  19. JAVA实现邮件发送功能(账号注册验证码、账号激活等)
  20. springboot与springcloud的版本问题

热门文章

  1. C语言程序设计现代方法_数组(第八章)
  2. 解决iOS内存泄露
  3. ubuntu 安装遇到黑屏
  4. iOS - Swift SingleClass 单例类
  5. iOS - Widget 小部件
  6. [转载] 根据多年经验整理的《互联网MySQL开发规范》
  7. js 立即执行函数,() .则前面的function 是表达式,不能是函数申明
  8. Python学习(7)数字
  9. python把元组组合成字典
  10. JavaWeb学习总结(十五)--过滤器的应用