大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
1、简要说明
1)本文基于spring5.1.7版本,采用ApplicationContext获取bean对象。
2)BeanFactory和ApplicationContext对于bean后置处理器还有所不同,需要注意,ApplicationContext会自动检测在配置文件中实现了BeanPostProcessor接口的所有bean,并把它们注册为后置处理器,然后在容器创建bean的适当时候调用它,因此部署一个后置处理器同部署其他的bean并没有什么区别。而使用BeanFactory实现的时候,bean 后置处理器必须通过代码显式地去注册。
2、Bean的生命周期
2.1、生命周期流程图
2.2、总体概述
我们知道一个对象的生命周期:创建(实例化-初始化)-使用-销毁,而在Spring中,Bean对象周期当然遵从这一过程,但是Spring提供了许多对外接口,允许开发者对三个过程(实例化、初始化、销毁)的前后做一些操作。
这里就实例化、初始化区别做一个说明,在Spring Bean中,实例化是为bean对象开辟空间(具体可以理解为构造函数的调用),初始化则是对属性的初始化,说的具体点,这里的属性初始化应该是属性的注入(构造函数也可以有属性的初始化语句,但不属于这一部分),属性注入是通过setter方法注入属性(不管是注解方式还是bean配置property属性方式,其实质都是通过属性的setter方法实现的)。
2.3、接口及方法介绍
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
1)Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
2)Bean级生命周期接口方法:BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法。每个Bean选择实现,可选择各自的个性化操作。
3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现(前者继承自后者),一般称它们的实现类为“后处理器”。这些接口是每个bean实例化或初始化时候都会调用。
4、工厂后处理器接口方法:这些方法也是容器级别的,但它们是在上下文装置配置文件之后调用,例如BeanFactoryPostProcessor、 CustomAutowireConfigurer等。
3、具体代码实现
1)定义一个bean类(CustomBean)
它实现了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这4个接口,同时有2个方法,对应配置文件中的init-method和destroy-method。
/**
* @author xf
* @description 自定义bean
* @date 2019/5/22 11:52
*/
public class CustomBean implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean {
private String name;
private String address;
private BeanFactory beanFactory;
private String beanName;
public CustomBean() {
System.out.println("第6步:【构造器】调用CustomBean的构造器实例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("第9步:【注入属性】注入属性name");
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
System.out.println("第10步:【注入属性】注入属性address");
this.address = address;
}
@Override
public String toString() {
return "CustomBean{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
// 通过spring的xml配置文件<bean>的init-method属性指定的初始化方法
public void xml_init() {
System.out.println("第16步:【init-method】调用<bean>的init-method属性指定的初始化方法");
}
// 通过spring的xml配置文件<bean>的destroy-method属性指定的初始化方法
public void xml_destroy() {
System.out.println("第21步:【destroy-method】调用<bean>的destroy-method属性指定的销毁方法");
}
// 这是BeanFactoryAware接口方法
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out
.println("第12步:【执行BeanFactoryAware接口的setBeanFactory方法】setBeanName后调用");
this.beanFactory = beanFactory;
}
// 这是BeanNameAware接口方法
@Override
public void setBeanName(String s) {
System.out.println("第11步:【执行BeanNameAware接口的setBeanName方法】属性注入后调用, 此时s = "+s);
this.beanName = s;
}
// 这是InitializingBean接口方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("第15步:【执行InitializingBean接口的afterPropertiesSet方法】在processBeforeInitialization之后,配置的xml_init之前调用");
}
// 这是DiposibleBean接口方法
@Override
public void destroy() throws Exception {
System.out.println("第20步:【执行DiposibleBean接口的destroy方法】在processAfterInitialization之后,配置的xml_destroy之前调用");
}
}
2)BeanFactoryPostProcessor类(工厂后处理器)
/**
* @author xf
* @description 工厂后处理器
* @date 2019/5/22 14:05
*/
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
public CustomBeanFactoryPostProcessor() {
System.out.println("第1步:这是BeanFactoryPostProcessor(工厂后处理器)实现类CustomBeanFactoryPostProcessor的构造器!!");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("第2步:调用BeanFactoryPostProcessor(工厂后处理器)实现类CustomBeanFactoryPostProcessor的方法postProcessBeanFactory。ApplicationContext容器初始化中refresh()中调用");
}
}
3)BeanPostProcessor类
/**
* @author xf
* @description BeanPostProcessor的实现类
* @date 2019/5/22 14:06
*/
public class InitialBeanPostProcessor implements BeanPostProcessor {
public InitialBeanPostProcessor() {
System.out.println("第4步:这是BeanPostProcessor实现类(InitialBeanPostProcessor)的构造器!!");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第14步:postProcessBeforeInitialization(BeanPostProcessor接口实现类InitialBeanPostProcessor的方法)对属性进行更改, bean = " + bean.getClass());
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第18步:postProcessAfterInitialization(BeanPostProcessor接口的方法)对属性进行更改, bean = " + bean.getClass());
return bean;
}
}
4)InstantiationAwareBeanPostProcessor 接口本质是BeanPostProcessor的子接口,一般我们继承Spring为其提供的适配器类InstantiationAwareBeanPostProcessor Adapter来使用它
/**
* @author xf
* @description 实例化处理器
* @date 2019/5/22 14:12
*/
public class InstanceBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public InstanceBeanPostProcessor() {
System.out.println("第3步:这是InstantiationAwareBeanPostProcessorAdapter实现类(InstanceBeanPostProcessor)构造器!!");
}
//实例化bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("第5步:实例化"+beanClass.getName()+"之前调用,即调用"+beanClass.getName()+"类构造函数之前调用 ");
return super.postProcessBeforeInstantiation(beanClass, beanName);
}
//实例化bean之后调用
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("第7步:返回boolean,bean实例化后调用,并且返回false则不会注入属性");
return super.postProcessAfterInstantiation(bean, beanName);
}
// 设置bean的某个属性时调用
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
System.out.println("第8步:postProcessProperties,在属性注入之前调用;beanName = " + beanName + ";属性名集合 : " + Arrays.toString(pvs.getPropertyValues()));
return super.postProcessProperties(pvs, bean, beanName);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第13步:postProcessBeforeInitialization(InstantiationAwareBeanPostProcessorAdapter实现类InstanceBeanPostProcessor的方法) ");
return super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第17步:postProcessAfterInitialization(InstantiationAwareBeanPostProcessorAdapter类的实现方法) ");
return super.postProcessAfterInitialization(bean, beanName);
}
}
5)Spring Bean的配置文件spring-bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="beanFactoryPostProcessor" class="com.spring.springbeancycle.CustomBeanFactoryPostProcessor">
</bean>
<bean id="instantiationAwareBeanPostProcessor" class="com.spring.springbeancycle.InstanceBeanPostProcessor">
</bean>
<bean id="beanPostProcessor" class="com.spring.springbeancycle.InitialBeanPostProcessor">
</bean>
<bean id="customBean" class="com.spring.springbeancycle.CustomBean" init-method="xml_init" destroy-method="xml_destroy">
<property name="name" value="小明"></property>
<property name="address" value="天涯海角"></property>
</bean>
</beans>
6)测试类
/**
* @author xf
* @description 测试类
* @date 2019/5/22 14:23
*/
public class SpringBeanTest {
public static void main(String[] args) {
System.out.println("====现在开始初始化容器====");
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring-bean.xml");
System.out.println("====容器初始化成功====");
CustomBean customBean = (CustomBean)context.getBean("customBean");
System.out.println("第19步:customBean = " + customBean);
System.out.println("====现在开始关闭容器!====");
((ClassPathXmlApplicationContext)context).close();
}
}
7)测试结果
第1步:这是BeanFactoryPostProcessor(工厂后处理器)实现类CustomBeanFactoryPostProcessor的构造器!!
第2步:调用BeanFactoryPostProcessor(工厂后处理器)实现类CustomBeanFactoryPostProcessor的方法postProcessBeanFactory。ApplicationContext容器初始化中refresh()中调用
第3步:这是InstantiationAwareBeanPostProcessorAdapter实现类(InstanceBeanPostProcessor)构造器!!
第4步:这是BeanPostProcessor实现类(InitialBeanPostProcessor)的构造器!!
第5步:实例化com.spring.springbeancycle.CustomBean之前调用,即调用com.spring.springbeancycle.CustomBean类构造函数之前调用
第6步:【构造器】调用CustomBean的构造器实例化
第7步:返回boolean,bean实例化后调用,并且返回false则不会注入属性
第8步:postProcessProperties,在属性注入之前调用;beanName = customBean;属性名集合 : [bean property 'name', bean property 'address']
第9步:【注入属性】注入属性name
第10步:【注入属性】注入属性address
第11步:【执行BeanNameAware接口的setBeanName方法】属性注入后调用, 此时s = customBean
第12步:【执行BeanFactoryAware接口的setBeanFactory方法】setBeanName后调用
第13步:postProcessBeforeInitialization(InstantiationAwareBeanPostProcessorAdapter实现类InstanceBeanPostProcessor的方法)
第14步:postProcessBeforeInitialization(BeanPostProcessor接口实现类InitialBeanPostProcessor的方法)对属性进行更改, bean = class com.spring.springbeancycle.CustomBean
第15步:【执行InitializingBean接口的afterPropertiesSet方法】在processBeforeInitialization之后,配置的xml_init之前调用
第16步:【init-method】调用<bean>的init-method属性指定的初始化方法
第17步:postProcessAfterInitialization(InstantiationAwareBeanPostProcessorAdapter类的实现方法)
第18步:postProcessAfterInitialization(BeanPostProcessor接口的方法)对属性进行更改, bean = class com.spring.springbeancycle.CustomBean
====容器初始化成功====
第19步:customBean = CustomBean{name='小明', address='天涯海角'}
====现在开始关闭容器!====
第20步:【执行DiposibleBean接口的destroy方法】在processAfterInitialization之后,配置的xml_destroy之前调用
第21步:【destroy-method】调用<bean>的destroy-method属性指定的销毁方法
4、流程总结
1、实例化一个Bean--也就是我们常说的new;
2、按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;
3、如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值
4、如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);
5、如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);
6、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;
7、如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
8、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;
注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。
9、当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;
10、最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
参考地址:
https://www.cnblogs.com/zrtqsk/p/3735273.html
https://uule.iteye.com/blog/2094609
https://blog.csdn.net/a327369238/article/details/52193822
https://www.cnblogs.com/kenshinobiy/p/4652008.html
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/192640.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...