http://blog.csdn.net/hhdem/article/details/1802701

InitializingBean
Spirng的InitializingBean为bean提供了定义初始化方法的方式。InitializingBean是一个接口,它仅仅包含一个方法:afterPropertiesSet()。

 
Bean实现这个接口,在afterPropertiesSet()中编写初始化代码:
package research.spring.beanfactory.ch4; import org.springframework.beans.factory.InitializingBean; publicclass LifeCycleBean implements InitializingBean{ publicvoid afterPropertiesSet() throws Exception { System.out.println("LifeCycleBean initializing..."); } }

在xml配置文件中并不需要对bean进行特殊的配置:
xml version="1.0" encoding="UTF-8"?>DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans><bean name="lifeBean" class="research.spring.beanfactory.ch4.LifeCycleBean">bean>beans>

编写测试程序进行测试:
package research.spring.beanfactory.ch4; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; publicclass LifeCycleTest { publicstaticvoid main(String[] args) { XmlBeanFactory factory=new XmlBeanFactory(new ClassPathResource( "research/spring/beanfactory/ch4/context.xml")); factory.getBean("lifeBean"); } }

运行上面的程序我们会看到:“LifeCycleBean initializing...”,这说明bean的afterPropertiesSet已经被Spring调用了。
Spring在设置完一个bean所有的合作者后,会检查bean是否实现了InitializingBean接口,如果实现就调用bean的afterPropertiesSet方法。

SHAPE  /* MERGEFORMAT

装配bean的合作者
查看bean是否实现InitializingBean接口
调用afterPropertiesSet方法
init-method
Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起了。通常情况下我不鼓励bean直接实现InitializingBean,可以使用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法。
写一个java class,这个类不实现任何Spring的接口。定义一个没有参数的方法init()。
package research.spring.beanfactory.ch4; publicclass LifeCycleBean{ publicvoid init(){ System.out.println("LifeCycleBean.init..."); } }

在Spring中配置这个bean:
xml version="1.0" encoding="UTF-8"?>DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans><bean name="lifeBean" class="research.spring.beanfactory.ch4.LifeCycleBean"  init-method="init">bean>beans>

当Spring实例化lifeBean时,你会在控制台上看到” LifeCycleBean.init...”。
 
Spring要求init-method是一个无参数的方法,如果init-method指定的方法中有参数,那么Spring将会抛出java.lang.NoSuchMethodException
init-method指定的方法可以是public、protected以及private的,并且方法也可以是final的。
init-method指定的方法可以是声明为抛出异常的,就像这样:
final protected void init() throws Exception{
System.out.println("init method...");
if(true) throw new Exception("init exception");
}
如果在init-method方法中抛出了异常,那么Spring将中止这个Bean的后续处理,并且抛出一个org.springframework.beans.factory.BeanCreationException异常。
InitializingBean和init-method可以一起使用,Spring会先处理InitializingBean再处理init-method。
org.springframework.beans.factory.support. AbstractAutowireCapableBeanFactory完成一个Bean初始化方法的调用工作。 AbstractAutowireCapableBeanFactory是XmlBeanFactory的超类,再 AbstractAutowireCapableBeanFactory的invokeInitMethods方法中实现调用一个Bean初始化方法:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.java:
//…… //在一个bean的合作者设备完成后,执行一个bean的初始化方法。protectedvoid invokeInitMethods(String beanName, Object bean, RootBeanDefinition mergedBeanDefinition) throws Throwable { //判断bean是否实现了InitializingBean接口if (bean instanceof InitializingBean) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '"+ beanName +"'"); } //调用afterPropertiesSet方法 ((InitializingBean) bean).afterPropertiesSet(); } //判断bean是否定义了init-methodif(mergedBeanDefinition!=null&&mergedBeanDefinition.getInitMethodName() !=null) { //调用invokeCustomInitMethod方法来执行init-method定义的方法 invokeCustomInitMethod(beanName, bean, mergedBeanDefinition.getInitMethodName()); } } //执行一个bean定义的init-method方法protectedvoid invokeCustomInitMethod(String beanName, Object bean, String initMethodName) throws Throwable { if (logger.isDebugEnabled()) { logger.debug("Invoking custom init method '"+ initMethodName +"' on bean with name '"+ beanName +"'"); } //使用方法名,反射Method对象 Method initMethod = BeanUtils.findMethod(bean.getClass(), initMethodName, null); if (initMethod ==null) { thrownew NoSuchMethodException( "Couldn't find an init method named '"+ initMethodName +"' on bean with name '"+ beanName +"'"); } //判断方法是否是publicif (!Modifier.isPublic(initMethod.getModifiers())) { //设置accessible为true,可以访问private方法。 initMethod.setAccessible(true); } try { //反射执行这个方法 initMethod.invoke(bean, (Object[]) null); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } //………..

通过分析上面的源代码我们可以看到,init-method是通过反射执行的,而afterPropertiesSet是直接执行的。所以 afterPropertiesSet的执行效率比init-method要高,不过init-method消除了bean对Spring依赖。在实际使用时我推荐使用init-method。
需要注意的是Spring总是先处理bean定义的InitializingBean,然后才处理init-method。如果在Spirng处理InitializingBean时出错,那么Spring将直接抛出异常,不会再继续处理init-method。

如果一个bean被定义为非单例的,那么afterPropertiesSet和init-method在bean的每一个实例被创建时都会执行。单例 bean的afterPropertiesSet和init-method只在bean第一次被实例时调用一次。大多数情况下 afterPropertiesSet和init-method都应用在单例的bean上。

spring的InitializingBean介绍相关推荐

  1. 【Spring源码】从源码实现的角度解析spring的InitializingBean的afterPropertiesSet方法和init-method区别和应用

    InitializingBean spring的InitializingBean为bean提供了定义初始化方法的方式.InitializingBean是一个接口,只包含一个方法:afterProper ...

  2. Spring Security 基本介绍,初窥路径

    Spring Security 基本介绍和环境搭建 实验介绍 Spring Security 是一个非常强大的身份验证和授权控制框架.为了满足企业项目的不同需求,它提供了很多定制化开发的解决方案,通过 ...

  3. Spring Cloud Gateway介绍(二)

    Spring Cloud Gateway介绍(一) 全局Filters GlobalFilter与GatewayFilter具有一样的接口. 这些全局过滤器都有对应的配置类,例如: org.sprin ...

  4. 《springcloud超级入门》Spring Cloud是什么?Spring Cloud版本介绍《二》

    Spring cloud是一系列框架的有序集合.它利用 Spring Boot 的开发便利性,巧妙地简化了分布式系统基础设施的开发,如服务注册.服务发现.配置中心.消息总线.负载均衡.断路器.数据监控 ...

  5. Spring框架Runtime介绍(导包)

    一.Spring框架Runtime介绍,如图 1.1 Test: Spring提供测试功能 1.2 Core Container:Spring核心容器,Spring启动的基本条件, 1.2.1 Bea ...

  6. 消费者驱动的契约测试 Spring Cloud Contract介绍

    消费者驱动的契约测试 Spring Cloud Contract介绍 什么是契约测试 测试是软件流程中非常重要,不可或缺的一个环节.一般的测试分为单元测试,集成测试,端到端的手工测试,这也是构成测试金 ...

  7. 服务监控 Spring Boot Actuator 介绍

    服务监控 Spring Boot Actuator 介绍 1. 概述 在本文中,我们将介绍Spring Boot Actuator.首先介绍一些Actuator的基础知识,然后详细讨论Spring B ...

  8. spring之基本介绍以及老版本框架的下载地址

    spring之基本介绍以及老版本框架的下载地址 第一:为什么要学习spring?学习spring能为我们在工作中的日常开发带来什么好处? 首先来了解一下spring:spring是一种开源的分层的相对 ...

  9. Spring Batch流程介绍

    Spring Batch流程介绍: 上图描绘了Spring Batch的执行过程.说明如下: 每个Batch都会包含一个Job.Job就像一个容器,这个容器里装了若干Step,Batch中实际干活的也 ...

最新文章

  1. Matlab数据的可视化 -- 视角与色彩控制
  2. 软件质量保证与测试笔记——江湖救急版
  3. cropbox php,jQuery用户头像裁剪插件cropbox.js实例分享
  4. 人员离职it检查_?「市安委会第十七检查组」值班人员擅离职守,变压器房随意出入...
  5. HUABASE :基于列存储的关系型数据库系统
  6. leetcode easy problem set
  7. Varnish的vcl子程序
  8. c# 程序员学习android(1)引导界面--viewpager的使用
  9. Java-UML类图
  10. LINUX基本操作(实验1)
  11. HTML网页设计:二、表单、表格
  12. transform模板函数调用tolower函数报错原因、解决办法
  13. 中国最牛逼的四大软件
  14. 2017计算机非全日制调剂,2017年非全日制硕士研究生调剂方案
  15. 微信小程序和百度小程序的登录 wx.login() swan.login() , 以及存在的问题处理
  16. Loadrunner之关联——用小故事理解
  17. 07 C++简单应用 编写一个摄氏度转华氏摄氏度的函数
  18. CDKF、UKF和EKF滤波算法
  19. mysql pacemaker_编译安装MySQL实现corosync+pacemaker+drbd+mysql高可用
  20. IT基础环境运维服务

热门文章

  1. Git之深入解析工作流程、常用命令与Reset模式分析
  2. 2019年第十届蓝桥杯 - 省赛 - C/C++大学B组 - H. 等差数列
  3. 2016年第七届蓝桥杯 - 国赛 - Java大学C组 - A. 平方末尾
  4. Java中集合(三)Stack
  5. 【Linux】一步一步学Linux——mesg命令(245)
  6. linux服务器备份软件下载,Linux服务器的常用备份方法 服务器系统备份方法
  7. python怎么打印字典_在python中打印字典的原始输入顺序
  8. MySQL的用户和授权
  9. idea 自动添加doc_interllij idea生成javadoc
  10. g++ vscode 环境选择_Visual Studio Code 配置C/C++环境