关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种:

第一种:通过注解@PostConstruct  和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作

  1. import javax.annotation.PostConstruct;
  2. import javax.annotation.PreDestroy;
  3. public class DataInitializer{
  4. @PostConstruct
  5. public void initMethod() throws Exception {
  6. System.out.println("initMethod 被执行");
  7. }
  8. @PreDestroy
  9. public void destroyMethod() throws Exception {
  10. System.out.println("destroyMethod 被执行");
  11. }
  12. }

第二种是:通过 在xml中定义init-method 和  destory-method方法

  1. public class DataInitializer{
  2. public void initMethod() throws Exception {
  3. System.out.println("initMethod 被执行");
  4. }
  5. public void destroyMethod() throws Exception {
  6. System.out.println("destroyMethod 被执行");
  7. }
  8. }
  1. <bean id="dataInitializer" class="com.somnus.demo.DataInitializer" init-method="initMethod" destory-method="destroyMethod"/>

第三种是:通过bean实现InitializingBean和 DisposableBean接口

  1. import org.springframework.beans.factory.DisposableBean;
  2. public class DataInitializer implements InitializingBean,DisposableBean{
  3. @Override
  4. public void afterPropertiesSet() throws Exception {
  5. System.out.println("afterPropertiesSet 被执行");
  6. }
  7. @Override
  8. public void destroy() throws Exception {
  9. System.out.println("destroy 被执行");
  10. }
  11. }

其中第一种和第二种是同一种形式,只不过一种xml配置,另外一种采用注解形式罢了,有很大区别的是第三种,

如果同一个bean同时采用两种方式初始化的时候执行某个方法,首先在执行顺序上就会体现出来。

先执行afterPropertiesSet(),

后执行initMethod()

这里我们看下源码

这方式在spring中是怎么实现的?

通过查看spring的加载bean的源码类(AbstractAutowireCapableBeanFactory)可看出其中奥妙

AbstractAutowireCapableBeanFactory类中的invokeInitMethods讲解的非常清楚,源码如下:

  1. protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
  2. throws Throwable {
  3. //判断该bean是否实现了实现了InitializingBean接口,如果实现了InitializingBean接口,则只掉调用bean的afterPropertiesSet方法
  4. boolean isInitializingBean = (bean instanceof InitializingBean);
  5. if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
  6. if (logger.isDebugEnabled()) {
  7. logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
  8. }
  9. if (System.getSecurityManager() != null) {
  10. try {
  11. AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
  12. public Object run() throws Exception {
  13. //直接调用afterPropertiesSet
  14. ((InitializingBean) bean).afterPropertiesSet();
  15. return null;
  16. }
  17. },getAccessControlContext());
  18. } catch (PrivilegedActionException pae) {
  19. throw pae.getException();
  20. }
  21. }
  22. else {
  23. //直接调用afterPropertiesSet
  24. ((InitializingBean) bean).afterPropertiesSet();
  25. }
  26. }
  27. if (mbd != null) {
  28. String initMethodName = mbd.getInitMethodName();
  29. //判断是否指定了init-method方法,如果指定了init-method方法,则再调用制定的init-method
  30. if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
  31. !mbd.isExternallyManagedInitMethod(initMethodName)) {
  32. //进一步查看该方法的源码,可以发现init-method方法中指定的方法是通过反射实现
  33. invokeCustomInitMethod(beanName, bean, mbd);
  34. }
  35. }

总结:

1:spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过

init-method指定,两种方式可以同时使用

2:实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是

init-method方式消除了对spring的依赖

3:如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。

Spring中初始化bean和销毁bean的时候执行某个方法的详解的更多相关文章

  1. Spring中属性注入的几种方式以及复杂属性的注入详解

    在spring框架中,属性的注入我们有多种方式,我们可以通过set方法注入,可以通过构造方法注入,也可以通过p名称空间注入,方式多种多样,对于复杂的数据类型比如对象.数组.List.Map.Prope ...

  2. js数组中的find(), findIndex(), filter(), forEach(), some(), every(), map(), reduce()方法的详解和应用实例

    1. find()与findIndex() find()方法,用于找出第一个符合条件的数组成员.它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该 ...

  3. spring的初始化bean,销毁bean之前的操作详解

    我所知道的在spring初始化bean,销毁bean之前的操作有三种方式: 第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 第二种是 ...

  4. Spring中<ref local=""/>与<ref bean=""/>区别

    小 Spring中<ref local=""/>与<ref bean=""/>区别 (2011-03-19 19:21:58) 转载▼ ...

  5. Spring中的创建与销毁

    在bean中添加属性init-method="方法名" destroy-method="方法名" init-method        该方法是由spring容 ...

  6. spring中整合memcached,以及创建memcache的put和get方法

    spring中整合memcached,以及创建memcache的put和get方法: 1:在项目中导入memcache相关的jar包 2:memcache在spring.xml的配置: 代码: < ...

  7. [转]js中几种实用的跨域方法原理详解

    转自:js中几种实用的跨域方法原理详解 - 无双 - 博客园 // // 这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同 ...

  8. [PXE] Linux(centos6)中PXE 服务器搭建,PXE安装、启动及PXE理论详解

    [PXE] Linux(centos6)中PXE 服务器搭建,PXE安装.启动及PXE理论详解 本篇blog主要讲述了[PXE] linux(centos)PXE无盘服务器搭建,安装,启动及pxe协议 ...

  9. Spring初始化Bean或销毁Bean前执行操作的方式

    如果想在Spring初始化后,或者销毁前做某些操作,常用的设定方式有三种: 第一种:通过 在xml中定义init-method 和 destory-method方法 推荐使用,缺陷是只能在XML中使用 ...

随机推荐

  1. Windows / VS下不同类型变量转换

    [时间:2016-07] [状态:Open] [关键词:windows,vs,mfc,类型转换] 在实际编码中经常遇到不同类型及编码方式的字符串.变量之间的转换,比如Unicode->char. ...

  2. 【Java】LinkedBlockingQueue、PriorityQueue and ConcurrentLinkedQueue

    1.LinkedBlockingQueue: 基于链接节点的可选限定的blocking queue . 这个队列排列元素FIFO(先进先出). 队列的头部是队列中最长的元素. 队列的尾部是队列中最短时 ...

  3. 【php】https请求

    /** * 模拟提交参数,支持https提交 可用于各类api请求 * @param string $url : 提交的地址 * @param array $data :POST数组 * @param ...

  4. 移动app传统测试流程优化

    [本文出自天外归云的博客园] 概述 在传统的软件测试流程中,每一期需求从开发到上线都要经历从需求分析与评审.测试用例评审.开发.测试.发布的流程.其中测试包含了后台测试.前端web测试.客户端测试.后 ...

  5. IntelliJ IDEA maven库下载依赖包速度慢的问题

    Reference: https://blog.csdn.net/qq1501340219/article/details/54638158 在pom.xml中添加maven 依赖包时,我就发现不管是 ...

  6. Excel中功能清单转Project任务

    接:http://www.cnblogs.com/vipsoft/p/8495220.html 1.在E列输入公式: =IF(LEN(A2)>1,1,IF(LEN(B2)>1,2,IF(L ...

  7. Android学习笔记(38):Handler消息传递处理机制

    先说为什么须要Handler: Android的主线程又叫UI线程,用于处理与UI相关的时间.Android仅仅同意在主线程中改动UI组件,当我们在其它线程中须要改动UI界面时.就须要发送消息到主线程 ...

  8. 【Unity】制作简易定时器(Timer)

    最近开始学习Unity,也想开始学习写一些简单的博客. 在网上学习了一些关于定时器的写法,在此简单总结一下,方便自己以后用到时查阅. 需求:制作定时器,运行3秒后执行第一次,之后每隔3秒执行一次操作. ...

  9. css table第一列 宽度

    table{table-layout:fixed;}table tr td:first-child,table tr td:first-child{width:120px;} 首行第一个td定宽同列的 ...

  10. tabs 标签样式

    http://www.jq22.com/jquery-info17973 http://www.jq22.com/demo/elementTab201801262311/ 插件描述:基于element ...