@Bean 生命周期
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 生命周期的更多相关文章
- Spring之BeanFactory及Bean生命周期
1.spring通过BeanFactory灵活配置.管理bean,Spring对管理的bean没有任何特别的要求,完全支持对POJO的管理: 2.BeanFactory有个ApplicationCon ...
- Bean生命周期及BeanFactory
1.spring通过BeanFactory灵活配置.管理bean,Spring对管理的bean没有任何特别的要求,完全支持对POJO的管理: 2.BeanFactory有个ApplicationCon ...
- Spring Bean配置默认为单实例 pring Bean生命周期
Bean默认的是单例的. 如果不想单例需要如下配置:<bean id="user" class="..." scope="singleton&q ...
- Spring Bean 生命周期2
在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Sin ...
- Spring bean 生命周期验证
一.从源码注释看bean生命周期 从JDK源码上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为: 1.BeanNameAware s ...
- Spring:Bean生命周期
关于Bean生命周期,我在网上找了两张图: 图1: 图2: 总结起来就是: Bean构建: Bean对象创建 > @Autowired | @Resource> @PostConstruc ...
- Spring事务,Bean生命周期
一.事务相关: 1.Spring事务基于Spring AOP切面编程: 2.AOP基于代理模式,得到需要开启事务的代码的代理对象: 3.而没有开启事务的Service方法里调用了开启事务 @Trans ...
- 【不懂】spring bean生命周期
完整的生命周期(牢记): 1.spring容器准备 2.实例化bean 3.注入依赖关系 4.初始化bean 5.使用bean 6.销毁bean Bean的完整生命週期可以認為是從容器建立初始化Bea ...
- spring(二、bean生命周期、用到的设计模式、常用注解)
spring(二.bean生命周期.用到的设计模式.常用注解) Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的. ...
- spring bean 生命周期和 ? 作用域? spirng bean 相互依赖? jvm oom ? jvm 监控工具? ThreadLocal 原理
1. spring bean 生命周期 1. 实例化一个bean ,即new 2. 初始化bean 的属性 3. 如果实现接口 BeanNameAware ,调用 setBeanName 4. Bea ...
随机推荐
- Charles(网络封包分析工具)
一.what Charles工具是通过将自己设置成系统的网络访问代理服务器,使得所有的网络访问请求都通过它来完成,从而实现了网络封包的截取和分析. 它能实现以下 支持SSL代理:截取分析SSL的请求. ...
- 微信小程序 --- 绘画
cavans及context详解 绘画API的使用 游戏的制作
- Apache配置虚拟主机httpd-vhosts.conf
一.配置虚拟主机需要3个文件 1.Apache/conf/httpd.conf 2.Apache/conf/extra/httpd-vhosts.conf (这个地版本的apache可能没有,可自己 ...
- 03Del.ashx(删除班级)
03Del.ashx 数据库里定义个BOOL型,TRUE表示正常FALSE表示删除 using System; using System.Collections.Generic; using Syst ...
- Guava增强for循环
Guava的前身是Google Collections,是Google开发出的一个开源Java常用类库,包含了一些集合的便捷操作API.本文通过一些常用的例子来剖析Guava的奇妙之处. Guava是 ...
- MVC之AJAX异步提交表单
第一种用法: 在MVC中,依然可以使用ajax校验,跟在WebForm中的使用时一样的,唯一的区别就是将以前的URL路劲改为访问控制器下的行为 前台 <html> <head> ...
- SIFT算法的教程及源码
1.ubc:DAVID LOWE---SIFT算法的创始人,两篇巨经典经典的文章http://www.cs.ubc.ca/~lowe/[1] 2.cmu:YanKe---PCASIFT,总结的SIFT ...
- BBS - 文章详细页、点赞、踩灭
一.文章详细页 文章详细页:1.链接:<div><h5><a href="/blog/{{ article.user.username }}/articles/ ...
- Spring Boot+CXF搭建WebService
Spring Boot WebService开发 需要依赖Maven的Pom清单 <?xml version="1.0" encoding="UTF-8" ...
- oracel 服务详细介绍
中的方法成功安装Oracle 11g后,共有7个服务, 这七个服务的含义分别为: 1. Oracle ORCL VSS Writer Service: Oracle卷映射拷贝写入服务,VSS(Volu ...