bean生命周期:

实例bean

1.当调用者通过getBean(beanName)向容器请求某一个Bean时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,在实例化Bean之前,将调用接口的postProcessBeforeInstantiation()方法;

2.根据配置情况调用Bean构造函数或工厂方法实例化Bean;

3.如果容器注册了InstantiationAwareBeanPostProcessor接口,在实例化Bean之后,调用该接口的postProcessAfterInstantiation()方法,可在这里对已经实例化的对象进行一些"梳妆打扮";

4.如果Bean配置了属性信息,容器在这一步着手将配置值设置到Bean对应的属性中,不过在设置每个属性之前将先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues()方法;
**
**
初始化和使用bean

1:BeanNameAware的setBeanName():

如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。

2:BeanFactoryAware的setBeanFactory():

如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。

3:BeanPostProcessors的ProcessBeforeInitialization()

如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。

4:initializingBean的afterPropertiesSet():

如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法

5:Bean定义文件中定义init-method:

可以在Bean定义文件中使用"init-method"属性设定方法名称例如:

如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法

6:BeanPostProcessors的ProcessaAfterInitialization()

如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法

BeanPostProcessor后处理器定义了两个方法:

**       其一是postProcessBeforeInitialization()在第8步调用;其二是Object postProcessAfterInitialization(Object bean, String beanName)方法,这个方法在此时调用,容器再次获得对Bean进行加工处理的机会;**

**       如果在中指定Bean的作用范围为scope="prototype",将Bean返回给调用者,调用者负责Bean后续生命的管理,Spring不再管理这个Bean的生命周期。如果作用范围设置为scope="singleton",则将Bean放入到Spring IoC容器的缓存池中,并将Bean引用返回给调用者,Spring继续对这些Bean进行后续的生命管理;**

销毁bean

此时,Bean已经可以被应用系统使用,并且将保留在BeanFactory中知道它不在被使用。有两种方法可以将其从BeanFactory中删除掉

1:DisposableBean的destroy()

在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法

2:Bean定义文件中定义destroy-method

在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称,例如:

如果有以上设定的话,则进行至这个阶段时,就会执行destroy()方法,如果是使用ApplicationContext来生成并管理Bean的话则稍有不同,使用ApplicationContext来生成及管理Bean实例的话,在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行BeanPostProcessors的ProcessBeforeInitialization()及之后的流程。

代码:

package com.company;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import java.beans.PropertyDescriptor; public class Main{
public static void main(String[] args) {
//①下面两句装载配置文件并启动容器
Resource res = new ClassPathResource("beans.xml");
BeanFactory bf = new XmlBeanFactory(res); //②向容器中注册MyBeanPostProcessor后处理器
((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyBeanPostProcessor()); //③向容器中注册MyInstantiationAwareBeanPostProcessor后处理器
((ConfigurableBeanFactory)bf).addBeanPostProcessor(
new MyInstantiationAwareBeanPostProcessor());
//④第一次从容器中获取worker,将触发容器实例化该Bean,这将引发Bean生命周期方法的调用。
Worker worker1 = (Worker)bf.getBean("worker");
System.out.println("第一次从容器中获取worker");
worker1.printInfo();
System.out.println("修改第一次从容器中获取worker的workType");
worker1.setWorkType("正式工");
System.out.println("第一次从容器中获取worker(修改过后的)");
worker1.printInfo();
//⑤第二次从容器中获取worker,直接从缓存池中获取
System.out.println("第二次从容器中获取worker");
Worker worker2= (Worker)bf.getBean("worker");
worker2.printInfo();
//⑥查看worker1和worker2是否指向同一引用
System.out.println("查看worker1和worker2是否指向同一引用 ");
System.out.println("worker1==worker2:"+(worker1==worker2));
//⑦关闭容器
((XmlBeanFactory)bf).destroySingletons();
} }
//①管理Bean生命周期的接口
class Worker implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean {
private String name;
private String workType;
private int salary; public BeanFactory beanFactory;
private String beanName; public void Worker(){
System.out.println("调用worker()构造函数");
} public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getWorkType() {
return workType;
}
public void setWorkType(String workType) {
this.workType = workType;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public void printInfo() {
System.out.println("name:" + name + ";workType:" + workType + ";salary:"
+ salary);
}
//⑤DisposableBean接口方法
@Override
public void destroy() throws Exception {
System.out.println("----------------销毁bean----------------------");
System.out.println("调用DisposableBean.destroy()。"); }
//④InitializingBean接口方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("调用InitializingBean.afterPropertiesSet()。"); }
//③BeanNameAware接口方法
@Override
public void setBeanName(String arg0) {
System.out.println("----------------初始化bean----------------------");
System.out.println("调用BeanNameAware.setBeanName()。");
this.beanName = arg0; }
//②BeanFactoryAware接口方法
@Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out.println("调用BeanFactoryAware.setBeanFactory()。");
this.beanFactory = arg0;
} //⑥通过<bean>的init-method属性指定的初始化方法
public void myInit() {
System.out.println("调用init-method所指定的myInit(),将salary设置为600。");
this.salary = 600;
} //⑦通过<bean>的destroy-method属性指定的销毁方法
public void myDestroy() {
System.out.println("调用destroy-method所指定的myDestroy()。");
} } class MyBeanPostProcessor implements BeanPostProcessor { @Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if(beanName.equals("worker")){
Worker worker = (Worker)bean;
if(worker.getWorkType() == null){
System.out.println("调用BeanPostProcessor.postProcess AfterInitialization(), getWorkType为空,设置为默认临时工");
worker.setWorkType("临时工");
}
}
return bean;
} @Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if(beanName.equals("worker")){
Worker worker = (Worker)bean;
if(worker.getSalary() >= 1000){
System.out.println("调用BeanPostProcessor.postProcess BeforeInitialization(), 将salary调整为800。");
worker.setSalary(800);
}
}
return bean;
} } class MyInstantiationAwareBeanPostProcessor extends
InstantiationAwareBeanPostProcessorAdapter {
// ①接口方法:在实例化Bean前进行调用
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
System.out.println("----------------实例化bean----------------------");
// ①-1仅对容器中worker Bean进行处理
if ("worker".equals(beanName)) {
System.out
.println("InstantiationAware BeanPostProcessor. postProcess BeforeInstantiation");
}
return null;
} // ②接口方法:在实例化Bean后调用
public boolean postProcessAfterInstantiation(Object bean, String beanName)
throws BeansException {
// ②-1仅对容器中car Bean进行处理
if ("worker".equals(beanName)) {
System.out
.println("InstantiationAware BeanPostProcessor.postProcess AfterInstantiation");
}
return true;
} // ③接口方法:在设置某个属性时调用
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException { // ③-1仅对容器中wroker Bean进行处理,还可以通过pdst入参进行过滤,
// 仅对car的某个特定属性时进行处理。
if ("worker".equals(beanName)) {
System.out
.println("Instantiation AwareBeanPostProcessor.postProcess PropertyValues");
}
return pvs;
}
}

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="worker" class="com.company.Worker"
init-method="myInit"
destroy-method="myDestroy"
p:name="小强"
p:salary="1000"
/>
</beans>

Result:

----------------实例化bean----------------------
InstantiationAware BeanPostProcessor. postProcess BeforeInstantiation
InstantiationAware BeanPostProcessor.postProcess AfterInstantiation
Instantiation AwareBeanPostProcessor.postProcess PropertyValues
----------------初始化bean----------------------
调用BeanNameAware.setBeanName()。
调用BeanFactoryAware.setBeanFactory()。
调用BeanPostProcessor.postProcess BeforeInitialization(), 将salary调整为800。
调用InitializingBean.afterPropertiesSet()。
调用init-method所指定的myInit(),将salary设置为600。
调用BeanPostProcessor.postProcess AfterInitialization(), getWorkType为空,设置为默认临时工
第一次从容器中获取worker
name:小强;workType:临时工;salary:600
修改第一次从容器中获取worker的workType
第一次从容器中获取worker(修改过后的)
name:小强;workType:正式工;salary:600
第二次从容器中获取worker
name:小强;workType:正式工;salary:600
查看worker1和worker2是否指向同一引用
worker1==worker2:true
----------------销毁bean----------------------
调用DisposableBean.destroy()。
调用destroy-method所指定的myDestroy()。

http://www.kancloud.cn/evankaka/springlearning/119661

http://www.imooc.com/article/19449

https://my.oschina.net/guanhe/blog/1408505

http://blog.csdn.net/mack415858775/article/details/47721909

https://zhuanlan.zhihu.com/p/25459839

https://muyinchen.github.io/2017/08/23/Spring5%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-@Autowired/

http://www.shangyang.me/2017/04/05/spring-core-container-sourcecode-analysis-annotation-autowired/

@Bean 生命周期的更多相关文章

  1. Spring之BeanFactory及Bean生命周期

    1.spring通过BeanFactory灵活配置.管理bean,Spring对管理的bean没有任何特别的要求,完全支持对POJO的管理: 2.BeanFactory有个ApplicationCon ...

  2. Bean生命周期及BeanFactory

    1.spring通过BeanFactory灵活配置.管理bean,Spring对管理的bean没有任何特别的要求,完全支持对POJO的管理: 2.BeanFactory有个ApplicationCon ...

  3. Spring Bean配置默认为单实例 pring Bean生命周期

    Bean默认的是单例的. 如果不想单例需要如下配置:<bean id="user" class="..." scope="singleton&q ...

  4. Spring Bean 生命周期2

    在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Sin ...

  5. Spring bean 生命周期验证

    一.从源码注释看bean生命周期 从JDK源码上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为: 1.BeanNameAware s ...

  6. Spring:Bean生命周期

    关于Bean生命周期,我在网上找了两张图: 图1: 图2: 总结起来就是: Bean构建: Bean对象创建 > @Autowired | @Resource> @PostConstruc ...

  7. Spring事务,Bean生命周期

    一.事务相关: 1.Spring事务基于Spring AOP切面编程: 2.AOP基于代理模式,得到需要开启事务的代码的代理对象: 3.而没有开启事务的Service方法里调用了开启事务 @Trans ...

  8. 【不懂】spring bean生命周期

    完整的生命周期(牢记): 1.spring容器准备 2.实例化bean 3.注入依赖关系 4.初始化bean 5.使用bean 6.销毁bean Bean的完整生命週期可以認為是從容器建立初始化Bea ...

  9. spring(二、bean生命周期、用到的设计模式、常用注解)

    spring(二.bean生命周期.用到的设计模式.常用注解) Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的. ...

  10. spring bean 生命周期和 ? 作用域? spirng bean 相互依赖? jvm oom ? jvm 监控工具? ThreadLocal 原理

    1. spring bean 生命周期 1. 实例化一个bean ,即new 2. 初始化bean 的属性 3. 如果实现接口 BeanNameAware ,调用 setBeanName 4. Bea ...

随机推荐

  1. 2012Noip提高组Day2 T3 疫情控制

    题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控制疫情,不让疫情扩散到 ...

  2. struts2的核心和工作原理 <转>

    在学习struts2之前,首先我们要明白使用struts2的目的是什么?它能给我们带来什么样的好处? 设计目标 Struts设计的第一目标就是使MVC模式应用于web程序设计.在这儿MVC模式的好处就 ...

  3. linux下php安装

    nginx中配置php:  http://www.111cn.net/sys/nginx/64044.htm

  4. html5实现的一些效果

    一.网页换肤 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <ti ...

  5. Codeforces 603E Pastoral Oddities

    传送门:http://codeforces.com/problemset/problem/603/E [题目大意] 给出$n$个点,$m$个操作,每个操作加入一条$(u, v)$长度为$l$的边. 对 ...

  6. 判断手机访问还是pc访问

    function isMobile(){ // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) re ...

  7. C#知识

    2018年10月29日 1.类可以定义的位置: (1)单独定义一个class,在program类的同一个文件内 (2)单独定义一个class,在program类的不同一个文件内 (3)类内定义clas ...

  8. EL表达式经验教训 javax.el.PropertyNotFoundException 出错

    之所以是把他记下来,是因为这个低级错误 害的我找了老半天. 后台传了对象到页面,在页面中循环遍历获得对象某个属性值 如下: <c:forEach items="${resultMap. ...

  9. Scala高级语法

    一.隐式 implicit分类: (1)隐式参数 (2)隐式转换类型 (3)隐式类 特点:让代码变得更加灵活 (一)隐式参数 1.ImplicitTest object ImplicitTest { ...

  10. 约会安排---hdu4553(线段树,麻烦的区间覆盖)

      题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553 算是poj3667的加强版,建立两颗线段树,一个是DS区间,另一个是NS区间.那么根据题意, ...