鏈接:https://blog.csdn.net/knknknkn8023/article/details/107130806/
Spring中bean的生命周期(詳解)
1.四個主要階段
2.常用的擴展點
3.影響多個bean的接口
4.只調用一次的接口
5.與aware有關的接口
6.兩個生命周期接口
7.總結:
四個主要階段
Spring bean的生命周期只有四個主要階段,其他都是在這四個主要階段前后的擴展點,這四個階段是:
1.實例化 Instantiation
2.屬性賦值 Populate
3.初始化 Initialization
4.銷毀 Destruction
其中實例化和屬性賦值分別對應構造方法和setter方法的注入,初始化和銷毀是用戶能自定義擴展的兩個階段。
可通過查源碼的方式發現,他們都在doCreate()方法中,
// 忽略了無關代碼
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 實例化階段!
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 屬性賦值階段!
populateBean(beanName, mbd, instanceWrapper);
// 初始化階段!
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
可以發現,分別調用三種方法:
1.createBeanInstance() -> 實例化
2.populateBean() -> 屬性賦值
3.initializeBean() -> 初始化
而銷毀階段是在容器關閉時調用的,在ConfigurableApplicationContext類的close()中
常用的擴展點
影響多個bean的接口
兩個最重要的接口:
InstantiationAwareBeanPostProcessor
BeanPostProcessor
實現這兩個接口的bean,會自動切入到相應的生命周期中,其中InstantiationAwareBeanPostProcessor是作用於實例化階段的前后,BeanPostProcessor是作用於初始化階段的前后。
具體代碼如圖:
package cn.xmx.ioc.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import java.beans.PropertyDescriptor;
public class MyInstantiationAwareBeanPostProcessorAdapter extends InstantiationAwareBeanPostProcessorAdapter {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if(beanName.equals("car")){
System.out.println(beanName+"在實例化之前");
}
return super.postProcessBeforeInstantiation(beanClass, beanName);
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if(beanName.equals("car")){
System.out.println(beanName+"在實例化之后");
}
return super.postProcessAfterInstantiation(bean, beanName);
}
}
package cn.xmx.ioc.lifecycle;
import java.lang.reflect.Proxy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
//后置處理器
public class NdBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("NdBeanPostProcessor 在"+beanName+"對象初始化之【前】調用......");
if(beanName.equals("car")) {
return new CglibInterceptor().getIntance(bean.getClass());
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("NdBeanPostProcessor 在"+beanName+"對象初始化之【后】調用......");
return bean;
}
}
package cn.xmx.ioc.lifecycle;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MainConfig {
@Bean(name="car",initMethod="init",destroyMethod="destroy")
public Car getCar() {
return new Car("大黃蜂");
}
@Bean
public BeanPostProcessor getBeanPostProcessor() {
return new NdBeanPostProcessor();
}
@Bean
public InstantiationAwareBeanPostProcessorAdapter getIns(){
return new MyInstantiationAwareBeanPostProcessorAdapter();
}
}
package cn.xmx.ioc.lifecycle;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/*
四個主生命周期
(1)實例化之前干預 InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation()
1.實例化
(2)實例化之后干預 InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInstantiation()
2.填充屬性(給屬性賦值)
(1)初始化之前干預 BeanPostProcessor.postProcessBeforeInitialization()
3.初始化化(比如准備資源文件)
3) 屬性進行干預 ----修改屬性或屬性值
(2)初始化之后干預 BeanPostProcessor.postProcessAfterInitialization()
4.銷毀(釋放資源---對象從內存銷毀)
N個接口
1、干預多次
1)BeanPostProcessor
2、干預一次
1)Aware
*/
public class TestLifeCycle {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
Car car = (Car) context.getBean("car");
System.out.println(car);//toString
System.out.println("beanname:"+car.getBeanName());
System.out.println("beanfactory:"+car.getBeanFactory());
System.out.println("applicationContext:"+car.getApplicationContext());
}
}
只調用一次的接口
與aware有關的接口
BeanNameAware
BeanFactoryAware
ApplicationContextAware
需要實體類實現這些接口,分別調用 Bean 的 setBeanName() 方法傳入當前 Bean 的 id 值,調用 setBeanFactory() 方法傳入當前工廠實例的引用,調用 setApplicationContext() 方法傳入當前 ApplicationContext 實例的引用。
具體代碼如下圖所示:
package cn.xmx.ioc.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Car implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {
private String name;
private String beanName;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
public void init() {
System.out.println("car 在初始化---加載資源");
}
public void destroy() {
System.out.println("car 在銷毀---釋放資源");
}
public Car() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Car(String name) {
super();
this.name = name;
System.out.println("car實例化了");
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("beanFactory:"+beanFactory);
this.beanFactory = beanFactory;
}
public BeanFactory getBeanFactory(){
return this.beanFactory;
}
public void setBeanName(String s) {
System.out.println("beanName:"+s);
this.beanName = s ;
}
public String getBeanName() {
return this.beanName;
}
public ApplicationContext getApplicationContext() {
return this.applicationContext;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("applicationContext:"+applicationContext);
this.applicationContext = applicationContext;
}
}
兩個生命周期接口
實例化和屬性賦值都是Spring幫助我們做的,能夠自己實現的有初始化和銷毀兩個生命周期階段。
1.InitializingBean 對應生命周期的初始化階段,在源碼的invokeInitMethods(beanName, wrappedBean, mbd);方法中調用。
2.DisposableBean 類似於InitializingBean,對應生命周期的銷毀階段,以ConfigurableApplicationContext#close()方法作為入口,實現是通過循環取所有實現了DisposableBean接口的Bean然后調用其destroy()方法 。
總結:
Bean 生命周期的整個執行過程描述如下:
1.如果創建了一個類繼承了InstantiationAwareBeanPostProcessorAdapter接口,並在配置文件中配置了該類的注入,即InstantiationAwareBeanPostProcessorAdapter和bean關聯,則Spring將調用該接口的postProcessBeforeInstantiation()方法。
2.根據配置情況調用 Bean 構造方法或工廠方法實例化 Bean。
3.如果InstantiationAwareBeanPostProcessorAdapter和bean關聯,則Spring將調用該接口的postProcessAfterInstantiation()方法。
4.利用依賴注入完成 Bean 中所有屬性值的配置注入。
5.如果 Bean 實現了 BeanNameAware 接口,則 Spring 調用 Bean 的 setBeanName() 方法傳入當前 Bean 的 id 值。
6.如果 Bean 實現了 BeanFactoryAware 接口,則 Spring 調用 setBeanFactory() 方法傳入當前工廠實例的引用。
7.如果 Bean 實現了 ApplicationContextAware 接口,則 Spring 調用 setApplicationContext() 方法傳入當前 ApplicationContext 實例的引用。
8.如果 BeanPostProcessor 和 Bean 關聯,則 Spring 將調用該接口的預初始化方法 postProcessBeforeInitialzation() 對 Bean 進行加工操作,此處非常重要,Spring 的 AOP 就是利用它實現的。
9.如果 Bean 實現了 InitializingBean 接口,則 Spring 將調用 afterPropertiesSet() 方法。
10.如果在配置文件中通過 init-method 屬性指定了初始化方法,則調用該初始化方法。
11.如果 BeanPostProcessor 和 Bean 關聯,則 Spring 將調用該接口的初始化方法 postProcessAfterInitialization()。
注意:以上工作完后才能以后就可以應用這個bean了,那這個bean是一個singleton的,所以一般這種情況下我們調用同一個id的bean會是在內容地址相同的實例,當然在spring配置文件中也可以配置非Singleton。
12.如果 Bean 實現了 DisposableBean 接口,則 Spring 會調用 destory() 方法將 Spring 中的 Bean 銷毀;如果在配置文件中通過 destory-method 屬性指定了 Bean 的銷毀方法,則 Spring 將調用該方法對 Bean 進行銷毀。