spring (學習記錄)bean的生命週期
阿新 • • 發佈:2018-12-27
借鑑:https://www.cnblogs.com/ooooevan/p/5804269.html
下面看實驗:
呼叫下面時,就建立了容器和物件
ApplicationContext ctx = new ClassPathXmlApplicationContext("cycle.xml");
那它又是怎樣一步步建立的呢?要銷燬怎麼銷燬?
用一個例子來看
package com.beans.cycle.Car; public class Car { private String brand; public Car(){ System.out.println("建構函式。。"); } public String getBrand() { System.out.println("返回屬性。。"); return brand; } public void setBrand(String brand) { this.brand = brand; System.out.println("設定屬性。。"); } public void init(){ System.out.println("init()。。"); } public void destroy(){ System.out.println("destroy()。。"); } }
xml中用init-mehod、 destroy-method表示呼叫初始化函式和銷燬函式
<bean id="car" class="com.beans.cycle.Car" init-method="init" destroy-method="destroy">
<property name="brand" value="Aodi"></property>
</bean>
執行主類
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("cycle.xml"); Car car=(Car)ctx.getBean("car"); System.out.println(car); //關閉IOC容器 ctx.close();
輸出:
建構函式。。//構造器
設定屬性。。//setter方法
init()。。
car[brand=Aodi] //返回這個bean
destroy()。。//容器關閉時呼叫這個方法
先呼叫建構函式和設定屬性,然後再init()。
建立Bean後置處理器
Bean後置處理器允許在呼叫初始化方法前後對Bean進
行額外的處理.
Bean後置處理器對I0C容器裡的所有Bean例項逐一處
理,而非單一例項.其典型應用是:檢查Bean屬性的正確性鹹根據特定的標準更改Bean的屬性.
對Bean 後置處理器而言,需要實現BeanPostProcessor介面.在初始化方法被呼叫前後,Spring將把每個Bean例項分別傳遞給上述介面的以下兩個方法:postProcessBeforeInitialization和postProcessAfterInitialization
bean後置處理器:檢查bean屬性的正確性或根據需要修改屬性,要實現BeanPostProcessor介面
寫一個實現類MyBeanPostProcessor
package com.beans.cycle.Car;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override //before
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessBeforeInitialization: "+bean +beanName);
return bean;
}
@Override //after
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessAfterInitialization: "+bean +beanName);
return bean;
}
}
xml
<bean id="car" class="com.beans.cycle.Car" init-method="init" destroy-method="destroy">
<property name="brand" value="Aodi"></property>
</bean>
<!--配置bean後置處理器,不需要配置id-->
<bean class="com.beans.cycle.Car"></bean>
跑一下,注意:一個再init之前呼叫,一個再init之後呼叫
建構函式。。
設定屬性。。
postProcessBoforeInitialization: car[brand=Aodi], car
init()。。
postProcessAfterInitialization: car[brand=Aodi], car
car[brand=Aodi]
destroy()。。
如何修改屬性? 在介面函式中修改
package com.beans.cycle.Car;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessBeforeInitialization: "+bean +beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessAfterInitialization: "+bean +beanName);
Car car = (Car) bean; // 獲取要修改的bean物件
car.setBrand("Ford"); //修改屬性
return bean;
}
}
注意:上面的bean是bean例項本身;beanName指IOC容器配置的bean的名字
這樣,就成功修改了屬性,輸出:
建構函式。。
設定屬性。。
postProcessBoforeInitialization:car[brand=Aodi], car
init()。。
postProcessAfterInitialization: car[brand=Aodi], car
car[brand=Ford]
destroy()。。
還可以過濾,因為處理所有bean時,可能對某些進行操作
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessBeforeInitialization: "+bean +beanName);
if("car".equals(beanName)){
//過濾的操作
}
return bean;
}