在spring开发中,我们定义bean
经常会需要用到beanFactory对象,这就需要实现BeanFactoryAware这种类型的接口,它有一个setBeanFactory方法
 
在xml中配置bean 的时候,我们也可以指定initMethod方法
 
在bean类定义的时候可以实现InitializingBean,提供一个afterPropertiesSet方法的实现
 
 
以上者3中情况我们经常用到,下面来分析一下spring是如何处理这3种情况的,他们的调用时机是怎么样的?
 
 
在AbstractAutowireCapableBeanFactory类中
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//...省略很多代码 下面开始初始化 关键就是两个步骤
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); //这里执行了注入属性和依赖的操作
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);//这里执行了initMethod 和 afterPropertiesSet
}
}
//...省略很多代码
return exposedObject;
}

 重点看initializeBean(beanName, exposedObject, mbd)

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
invokeAwareMethods(beanName, bean); return null;
}
}, getAccessControlContext());
}
else {
//这里判断是BeanFactoryAware, ServletContextAware之类的aware类型,如果是的话就执行对于的Aware方法
//把beanFactory啊 servletContext啊之类的依赖set进去
invokeAwareMethods(beanName, bean);
} Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//如果实现了BeanPostProcessor接口 这里会执行postProcessBeforeInitialization方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//这里就开始执行initMethod 和 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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

进入invokeInitMethods(beanName, wrappedBean, mbd);

    protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);//先判断是否实现了InitializingBean接口
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
//.....省略很多代码
else {
//执行afterPropertiesSet()方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//如果配置了initMethod 就执行initMethod方法 这里只是取到了方法名,显然是要通过反射调用了
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
经过这些源码的分析 可以得出结论
首先这些过程都在很重要的抽象类AbstractAutowireCapableBeanFactory抽象类中 这个类就是常用的DefaultListableBeanFactory的父类
1.spring先根据beanDefinition创建出了bean 的实例
 
2.执行了populateBean方法 把属性和依赖都注入了  
 
3.执行了 initializeBean(beanName, exposedObject, mbd);方法 这里面才进行了Aware相关方法,afterPropertiesSet 和 initMethod 方法的调用
可见这3种方法调用又都是在bean实例已经创建好,且属性值和依赖的其他bean实例都已经注入以后 才得到调用的
 
4.后面的代码可以看出 Aware相关方法最先执行,afterPropertiesSet 第二执行  ,initMethod 方法最后执行
 
另外多说一句 afterPropertiesSet方法是很有用的,比如 AOP事务管理用到的类,TransactionProxyFactoryBean 就是利用afterPropertiesSet方法事先把事务管理器
TransactionManager的代理类对象给生成好了,后面调用FactoryBean对象的getObject方法的时候,就直接把这个代理对象返回出去了。

initMethod 和 afterPropertiesSet 以及 AwareMethod方法的执行时机的更多相关文章

  1. Android中的Sqlite中的onCreate方法和onUpgrade方法的执行时机

    1.今天在做数据库升级的时候,遇到一个问题,就是onCreate方法和onUpgrade方法的执行时机的问题,这个当时在操作的时候,没有弄清楚,很是迷糊,后来看了相关的博客由于转发受限所以copy了一 ...

  2. Android中的Sqlite中的onCreate方法和onUpgrade方法的执行时机--(转)

    原文:http://blog.csdn.net/jiangwei0910410003/article/details/46536329 今天在做数据库升级的时候,遇到一个问题,就是onCreate方法 ...

  3. MVC源码分析 - Action/Result 过滤器执行时机

    前面 的篇章, 解析了Action方法的查找, 以及 Authorize, Action, Result, Error 过滤器的加载时机. 也花了两篇去看授权和错误过滤器的使用. 但是对于 Actio ...

  4. 简单比较init-method,afterPropertiesSet和BeanPostProcessor

    一.简单介绍 1.init-method方法,初始化bean的时候执行,可以针对某个具体的bean进行配置.init-method需要在applicationContext.xml配置文档中bean的 ...

  5. 在Spring Bean的生命周期中各方法的执行顺序

    Spring 容器中的 Bean 是有生命周期的,Spring 允许在 Bean 在初始化完成后以及 Bean 销毁前执行特定的操作,常用的设定方式有以下十种: 通过实现 InitializingBe ...

  6. 【hibernate 执行方法未插入数据库】hibernate的save方法成功执行,但是未插入到数据库

    今天做项目,碰上这个问题: hibernate的save方法成功执行,但是未插入到数据库. Dao层代码: @Override public void save(T t) { this.getSess ...

  7. C# 给某个方法设定执行超时时间 C#如何控制方法的执行时间,超时则强制退出方法执行 C#函数运行超时则终止执行(任意参数类型及参数个数通用版)

    我自己写的 /// <summary> /// 函数运行超时则终止执行(超时则返回true,否则返回false) /// </summary> /// <typepara ...

  8. 转 C# 给某个方法设定执行超时时间

    在某些情况下(例如通过网络访问数据),常常不希望程序卡住而占用太多时间以至于造成界面假死. 在这时.我们可以通过Thread.Thread + Invoke(UI)或者是 delegate.Begin ...

  9. -tableView: cellForRowAtIndexPath:方法不执行问题

    今天在学习UItableView 的时候,定义了一个属性 @property (weak, nonatomic) NSMutableArray *dataList: 在ViewDidLoad方法方法中 ...

随机推荐

  1. 转 Xcode磁盘空间大清理

    http://www.iwangke.me/2013/09/09/clean-xcode-to-free-up-disk-space/#jtss-tsina 我的设备是Macbook Air 13’ ...

  2. 理解SVG坐标系统和变换: 建立新视窗

    在SVG绘制的任何一个时刻,你可以通过嵌套<svg>或者使用例如<symbol>的元素来建立新的viewport和用户坐标系.在这篇文章中,我们将看一下我们如何这样做,以及这样 ...

  3. cannot find the word template:WordToRqm.dot的解决方法

    powerdesigner安装后: C:"Program Files"Sybase"PowerDesigner 12"Add-ins"Microsof ...

  4. MVC Action 返回类型[转]

    一.         ASP.NET MVC 1.0 Result 几何? Action的返回值类型到底有几个?咱们来数数看. ASP.NET MVC 1.0 目前一共提供了以下十几种Action返回 ...

  5. 读取编码为utf-16le的文件并打印

    import codecs data = open('test.txt').read()if data[:2] == codecs.BOM_UTF16_LE:    data = data[2:]  ...

  6. oracle sys sysman system 介绍

    Oracle数据库中SYS.SYSTEM.DBSNMP.SYSMAN四用户的区别 SYS用户: SYS,默认密码为CHANGE_ON_INSTALL,当创建一个数据库时,SYS用户将被默认创建并授予D ...

  7. UltraISO PE(软碟通) v9.6.2.3059 注册码

    注册码: 王涛7C81-1689-4046-626F

  8. zookeeper系列(一)安装

    zookeeper是一个分布式应用协调服务,主要用来解决分布式应用配置项的管理.同步服务.集群管理等,它由Java语言编写,但它支持Java和C两种编程语言接口:   环境部署 操作系统:centos ...

  9. (原)Eclipse Tomcat配置(2014.12.27——By小赞)

    Eclipse中配置自己已经安装的Tomcat 首先为Eclipse安装Tomcat插件: 进入Tomcat插件下载页:http://www.eclipsetotale.com/tomcatPlugi ...

  10. java.lang.RuntimeException: java.lang.ClassNotFoundException: cmd.CmdWordCount$MyMapper解决方法

    14/02/28 20:29:48 INFO mapred.JobClient: Task Id : attempt_201402281833_0004_m_000000_1, Status : FA ...