在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. ruby编程语言-学习笔记4(第4章 表达式和操作符)

    4.6.9 范围  Flip-Flops:  ..和... ..和... 操作符不是基于方法的,无法重定义.(优先级比较低) x+1 .. x*x   #可以认为是x+1 至 x*x 的范围 因为操作 ...

  2. 解决Dagger2和butterknife冲突

    dagger2 和 RxJava butterknife 以及 Retrofit使用起来非常酸爽 代码非常干净清晰 动手尝试 配置编译 DaggerAppComponent的时候 出现问题 配置dag ...

  3. Node.js 创建第一个应用

    如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi. 从这个角度看,整个"接收 HTTP 请求并提供 ...

  4. ARM--存储管理器

    初入领悟: 1. bank.L-bank的概念 2. s3c2440内部管理SDRAM寄存器配置 Frist part:原理分析 S3c2440为32位微处理器,其可访问空间为4G:但其中提供1G外设 ...

  5. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程06:技能播放的逻辑关系》

    6.技能播放的逻辑关系 技能播放概述: 当完成对技能输入与检测之后,程序就该对输入在缓存器中的按键操作与程序读取的技能表信息进行匹配,根据匹配结果播放相应的连招技能. 技能播放原理: 按键缓存器中内容 ...

  6. 通过js获取计算机内网ip,计算机名,mac地址

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  7. 【解决】hbase regionserver意外关机启动失败 [main] mortbay.log: tmpdir java.io.IOException: Permission denied

    错误信息: 015-12-24 10:57:26,527 INFO  [main] mortbay.log: jetty-6.1.26.cloudera.4 2015-12-24 10:57:26,5 ...

  8. (Step by Step)How to setup IP Phone Server(VoIP Server) for free.

    You must have heard about IP Phone and SIP (Software IP Phone).Nowadays standard PSTN phone are bein ...

  9. Asp.net多行文本框随内容增加而高度增加

    最近做一个项目,在一个多行文本框(TextBox)里显示新闻内容,由于内容有多有少,并且总是出现垂直滚动条,很不好看,笔者就想用一个法子,去掉垂直滚动条,并且文本框的高度随内容的增加而变大,使高度适应 ...

  10. PC-老鸟装机

    老鸟装机 一.硬件安装莫疏忽   1>安装硬盘有讲究     1.单硬盘+单光驱       IDE1----硬盘(Mastet接口)       IDE2----光驱(Mastet接口)    ...