一、緒論
這篇博文的代碼其實很早就有了(在看《精通spring4.x企業應用開發實踐》學習記錄的),只是我沒有把它寫成博文,今天突然想去翻翻,找半天才找到,所以我在此記錄一下,否則今後再想去看又找不到了,在此非常感謝作者,讓我看到了這麼細緻的spring開發書籍。本篇也是在作者書籍當中的代碼自己敲了過來,學習學習。
二、spring Bean介紹
spring的bean實例化會經歷多個階段,每個階段都爲bean處理不同的邏輯和控制
三,spring Bean 的初始化過程(生命週期)
1、我在這引入書中的一張圖
這張圖可謂是概括了bean的生命週期全部內容,堪稱經典。
我們可能會想那spring 會在什麼時候去實例化bean呢?別慌,下面就行答案(嘿嘿~~~)
這裏我百度的,地址:https://www.cnblogs.com/zhaoxinshanwei/p/8856318.html
Spring什麼時候實例化bean,首先要分2種情況
第一:如果你使用BeanFactory作爲Spring Bean的工廠類,則所有的bean都是在第一次使用該Bean的時候實例化
第二:如果你使用ApplicationContext作爲Spring Bean的工廠類,則又分爲以下幾種情況:
(1):如果bean的scope是singleton的,並且lazy-init爲false(默認是false,所以可以不用設置),則ApplicationContext啓動的時候就實例化該Bean,並且將實例化的Bean放在一個map結構的緩存中,下次再使用該Bean的時候,直接從這個緩存中取
(2):如果bean的scope是singleton的,並且lazy-init爲true,則該Bean的實例化是在第一次使用該Bean的時候進行實例化
(3):如果bean的scope是prototype的,則該Bean的實例化是在第一次使用該Bean的時候進行實例化
2、代碼實現之生命週期測試階段(代碼來自書籍中的測試)
定義bean 並且 implements Serializable,BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean
完整代碼:
package com.bean.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import java.io.Serializable;
/**
* bean生命週期(bean級)
*/
public class Car implements Serializable,BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean {
private String name;
private String color;
private int maxSpeed;
private BeanFactory beanFactory;
private String benaName;
public Car() {
System.out.println("調用 Car 的 構造函數。。");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("調用 setName()設置屬性");
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
//2、BenaFactoryAware接口方法
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("調用BenaFactoryAware接口的setBeanFactory()方法");
this.beanFactory=beanFactory;
}
//3、BeanNameAware接口方法
@Override
public void setBeanName(String benaName) {
System.out.println("調用BeanNameAware接口方法接口的setBeanName()方法");
this.benaName=benaName;
}
//4、InitializingBean接口方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("調用InitializingBean接口方法接口的afterPropertiesSet()方法");
}
//5、DisposableBean接口方法
@Override
public void destroy() throws Exception {
System.out.println("調用DisposableBean接口方法接口的destroy()方法");
}
//6、通過<bean>的init-method屬性指定初始化方法
public void myInit(){
System.out.println("調用init-method所指定的myInit()方法,並且將v屬性設置爲10000");
this.maxSpeed=10000;
}
//7、通過<bean>的destroy-method屬性指定初始化方法
public void myDestroy(){
System.out.println("調用destroy-method所指定的myDestroy()方法");
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", maxSpeed=" + maxSpeed +
", beanFactory=" + beanFactory +
", benaName='" + benaName + '\'' +
'}';
}
}
定義一個後置處理器
MyInstantiationAwareBeanPostProcessor 並且繼承 InstantiationAwareBeanPostProcessorAdapter 實現 Ordered
完整代碼:
package com.bean.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.core.Ordered;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
/**
* 後處理器(InstantiationAwareBeanPostProcessorAdapter 最終還是實現的是 BeanPostProcessor 接口)
*/
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements Ordered{
public MyInstantiationAwareBeanPostProcessor() {
super();
}
@Override
public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
return super.predictBeanType(beanClass, beanName);
}
@Override
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
return super.determineCandidateConstructors(beanClass, beanName);
}
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return super.getEarlyBeanReference(bean, beanName);
}
//1、接口方法,實例化bean前調用
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//僅對容器中的car bena處理
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
}
return null;
}
//2、接口方法,在bean實例化後調用
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
//2-1、僅對容器中的car baen處理
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
}
return true;
}
//3、接口方法,在設置某個屬性值時調用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
//3-1、僅對容器中的car baen處理
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return super.postProcessAfterInitialization(bean, beanName);
}
@Override
public int getOrder() {
return 0;
}
}
注意:InstantiationAwareBeanPostProcessorAdapter 最終也是實現BeanPostProcessor接口
我們再來定義一個 後處理器 MyBeanPostProcessor
完整代碼如下:
package spring.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
/**
* 後處理器
*/
public class MyBeanPostProcessor implements BeanPostProcessor,Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("car")){
Car car= (Car) bean;
if(car.getName()==null||car.getName()==""){
System.out.println("調用MyBeanPostProcessor的postProcessBeforeInitialization方法,並且設置 car 的名稱爲 ‘奧迪A1’");
car.setName("奧迪A1");
}
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(beanName.equals("car")){
Car car= (Car) bean;
if(car.getMaxSpeed()>=500){
System.out.println("調用MyBeanPostProcessor的postProcessAfterInitialization方法,並且設置 car 的MaxSpeed 爲500");
car.setMaxSpeed(500);
}
}
return bean;
}
@Override
public int getOrder() {
return 1;
}
}
定義一個 工廠 後處理器
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor
完整代碼如下:
package spring.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
* 工廠 後處理器
*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
//1、對car 的color 屬性進行“偷樑換柱”的加工操作
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {
BeanDefinition beanDefinition = bf.getBeanDefinition("car");
System.out.println("原來的color:"+beanDefinition.getPropertyValues().getPropertyValue("color").getValue());
System.out.println("原來的maxSpeed:"+beanDefinition.getPropertyValues().getPropertyValue("maxSpeed").getValue());
beanDefinition.getPropertyValues().addPropertyValue("color",
"粉紅色。。。@@@");
System.out.println("調用BeanFactoryPostProcessor接口的postProcessBeanFactory()方法");
}
}
最後來測試
package spring.lifecycle;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/**
* 讓容器裝載配置文件,然後分別註冊鎖提供的兩個後置處理器
*/
public class BeanLifeCycle {
private static void lifeCycleInBeanFactory(){
//1、下面兩句是裝載配置文件並且啓動容器
// ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("calsspath:applicationContext.xml");
Resource classPathResource = new ClassPathResource("applicationContext.xml");
BeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) defaultListableBeanFactory);
reader.loadBeanDefinitions(classPathResource);
//2、向容器註冊MyBeanPostProcessor後處理器
((ConfigurableBeanFactory)defaultListableBeanFactory).addBeanPostProcessor(new MyBeanPostProcessor());
//3、向容器註冊MyInstantiationAwareBeanPostProcessor後處理器
((ConfigurableBeanFactory)defaultListableBeanFactory).addBeanPostProcessor(
new MyInstantiationAwareBeanPostProcessor());
//4、第一次從容器中獲取car ,將觸發容器實例化該bean,這將引發bean生命週期的方法調用
Car car = defaultListableBeanFactory.getBean("car", Car.class);
car.setColor("紅色");
//5、第二次從容器中獲取car,直接從緩存池中獲取
Car car1 = defaultListableBeanFactory.getBean("car", Car.class);
//6、查看car與car1是否爲同一個對象
System.out.println("(car==car1) :"+(car==car1));
//7、關閉容器
((ConfigurableBeanFactory) defaultListableBeanFactory).destroySingletons();
}
public static void main(String[] args) {
lifeCycleInBeanFactory();
}
}
運行結果:
總結:ApplicationContext是自動註冊後置處理器,而beanFactor需要手動調用addBeanPostProcessor方法註冊
代碼中都有註釋,到此完畢!!!