Spring生命周期最詳解
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
目的
在大三開始學(xué)習(xí)spring時(shí),老師就說spring bean周期非常重要,當(dāng)時(shí)也有仔細(xì)看,但是說實(shí)話搞不大懂,后面工作面試也問過,還是有點(diǎn)模糊,就是沒有掌握好,進(jìn)行深入理解,這次“老大”又問到了。不允許再回避了,所以這次堅(jiān)決搞明白,理解生命周期作用,為啥要這樣設(shè)計(jì),我們能在生命周期做哪些更高層次的編程。
生命周期流程圖
先總體看下spring的生命周期流程圖,實(shí)現(xiàn)(繼承)這些接口(抽象類)并在容器里注冊,就可以看到bean的生命周期會(huì)按下面流程進(jìn)行,后面會(huì)給出測試代碼。

可以看出設(shè)計(jì)策略是“先顧大局”-類似的操作BeanFactory一般出現(xiàn)在Bean之前,操作完Bean之后,BeanFactory會(huì)進(jìn)行“管理”;Bean操作的前提是應(yīng)用了BeanPostProcessor。
測試代碼
要被注冊的Person類
package springBeanTest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {
private String name;
private String address;
private int phone;
private BeanFactory beanFactory;
private String beanName;
public Person() {
System.out.println("【構(gòu)造器】調(diào)用Person的構(gòu)造器實(shí)例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【注入屬性】name");
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
System.out.println("【注入屬性】address");
this.address = address;
}
public int getPhone() {
return phone;
}
public void setPhone(int phone) {
System.out.println("【注入屬性】phone");
this.phone = phone;
}
// 這是BeanFactoryAware接口方法
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【BeanFactoryAware接口】調(diào)用setBeanFactory方法");
this.beanFactory = beanFactory;
}
// 這是BeanNameAware接口方法
public void setBeanName(String s) {
System.out.println("【BeanNameAware接口】調(diào)用setBeanName方法");
this.beanName = s;
}
// 這是DiposibleBean接口方法
public void destroy() throws Exception {
System.out.println("【DiposibleBean接口】調(diào)用destroy方法");
}
// 這是InitializingBean接口方法
public void afterPropertiesSet() throws Exception {
System.out.println("【InitializingBean接口】調(diào)用afterPropertiesSet方法");
}
// 通過<bean>的init-method屬性指定的初始化方法
public void myInit() {
System.out.println("【init-method】調(diào)用<bean>的init-method屬性指定的初始化方法");
}
// 通過<bean>的destroy-method屬性指定的初始化方法
public void myDestory() {
System.out.println("【destroy-method】調(diào)用<bean>的destroy-method屬性指定的初始化方法");
}
}
實(shí)現(xiàn)BeanFactoryPostProcessor的類
package springBeanTest;
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{
public MyBeanFactoryPostProcessor() {
super();
System.out.println("這是BeanFactoryPostProcessor實(shí)現(xiàn)類構(gòu)造器??!");
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out
.println("BeanFactoryPostProcessor調(diào)用postProcessBeanFactory方法");
BeanDefinition bd = configurableListableBeanFactory.getBeanDefinition("person");
bd.getPropertyValues().addPropertyValue("phone", "110");
}
}
繼承InstantiationAwareBeanPostProcessorAdapter的類
package springBeanTest;
import java.beans.PropertyDescriptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
public class MyInstantiationAwareBeanPostProcessor extends
InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out
.println("這是InstantiationAwareBeanPostProcessorAdapter實(shí)現(xiàn)類構(gòu)造器??!");
}
// 接口方法、實(shí)例化Bean之前調(diào)用
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor調(diào)用postProcessBeforeInstantiation方法");
return null;
}
// 接口方法、實(shí)例化Bean之后調(diào)用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor調(diào)用postProcessAfterInitialization方法");
return bean;
}
// 接口方法、設(shè)置某個(gè)屬性時(shí)調(diào)用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor調(diào)用postProcessPropertyValues方法");
return pvs;
}
}
實(shí)現(xiàn)BeanPostProcessor的類
package springBeanTest;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor{
public MyBeanPostProcessor(){
System.out.println("這是BeanPostProcessor實(shí)現(xiàn)類構(gòu)造器?。?);
}
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization對屬性進(jìn)行更改");
return o;
}
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization對屬性進(jìn)行更改");
return o;
}
}
測試類BeanLifeCycle
package springBeanTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanLifeCycle {
public static void main(String[] args) {
System.out.println("現(xiàn)在開始初始化容器");
ApplicationContext factory = new ClassPathXmlApplicationContext("beans.xml");
System.out.println("容器初始化成功");
//得到Preson,并使用
Person person = factory.getBean("person",Person.class);
System.out.println(person);
System.out.println("現(xiàn)在開始關(guān)閉容器!");
((ClassPathXmlApplicationContext)factory).registerShutdownHook();
}
}
配置文件
<?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"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="beanPostProcessor" class="springBeanTest.MyBeanPostProcessor">
</bean>
<bean id="instantiationAwareBeanPostProcessor" class="springBeanTest.MyInstantiationAwareBeanPostProcessor">
</bean>
<bean id="beanFactoryPostProcessor" class="springBeanTest.MyBeanFactoryPostProcessor">
</bean>
<bean id="person" class="springBeanTest.Person" init-method="myInit"
destroy-method="myDestory" scope="singleton" p:name="張三" p:address="廣州"
p:phone="123567889"/>
</beans>
生命周期的接口和抽象類
大概了解了生命周期的流程和運(yùn)用到哪些接口和抽象類之后,下面開始進(jìn)一步深入了解他們的具體作用,按照流程往下一一介紹。
這里spring版本是4.1.8.RELEASE。
BeanFactoryPostProcessor接口
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
該接口只有一個(gè)postProcessBeanFactory方法,BeanFactoryPostProcessor:在bean factory標(biāo)準(zhǔn)初始化之后可以進(jìn)行修改。將加載所有bean定義,但是還沒有實(shí)例化bean。這個(gè)方法允許重新覆蓋或者添加屬性甚至快速的初始化bean。
初次看不知干嘛,關(guān)鍵在于參數(shù),可以利用參數(shù)做一些操作。
下面了解一下這個(gè)參數(shù)。
ConfigurableListableBeanFactory 提供分析、修改bean定義和預(yù)先實(shí)例化單例。這個(gè)BeanFactory的子接口不應(yīng)該是被使用于普通應(yīng)用程序中:BeanFactory和ListableBeanFactory鐵錚錚作為最經(jīng)典的用例;這個(gè)接口是僅應(yīng)該允許內(nèi)部框架使用,即使在訪問bean factory配置方法時(shí)也如此。
ConfigurableListableBeanFactory 的方法
freezeConfiguration():凍結(jié)全部bean定義,給被注冊的bean定義發(fā)信號告訴它們今后不再被修改和進(jìn)一步后續(xù)處理。它允許factory去積極緩存bean定義元數(shù)據(jù)。
getBeanDefinition(String beanName):根據(jù)指定的bean name返回被注冊的bean定義,允許訪問其屬性值和構(gòu)造函數(shù)參數(shù)值(可以在bean工廠后期處理期間被修改)。這個(gè)被返回的bean definition對象不應(yīng)該是副本而是原始在工廠被注冊的。這意味著如果需要它可以被轉(zhuǎn)換為更具體的實(shí)現(xiàn)類型。注意這個(gè)方法只能獲得本地工廠bean definition。
Iterator getBeanNamesIterator():返回由這個(gè)bean factory管理的所有bean name統(tǒng)一視圖。
void ignoreDependencyType(Class<?> type):忽略被給定注入依賴類型 ,例如String。
void ignoreDependencyInterface(Class<?> ifc) :忽略被給定注入依賴接口 。這個(gè)通常被使用由application contexts去注冊依賴,可以以多種方式實(shí)現(xiàn)。例如BeanFactory通過BeanFactoryAware,ApplicationContext 通過ApplicationContextAware。默認(rèn)情況下,僅BeanFactoryAware接口是被忽略,需要忽略其他接口,調(diào)用此方法。
boolean isAutowireCandidate(String beanName,DependencyDescriptor descriptor)throws NoSuchBeanDefinitionException :確認(rèn)這個(gè)被指定的bean是否是一個(gè)autowire候選,將被注入到其他聲明匹配類型的依賴的bean中。
isConfigurationFrozen():返回該工廠的bean definnitions是否被凍結(jié)。
preInstantiateSingletons():確保所有非懶加載的單例bean被實(shí)例化,包括factoryBeans。
void registerResolvableDependency(Class<?> dependencyType,Object autowiredValue):注冊一個(gè)特定類型依賴伴隨著相應(yīng)的autowired值。這個(gè)是準(zhǔn)備被用于應(yīng)該可以autowire而不是在這個(gè)工廠被定義的bean的工廠/上下文引用。例如 將ApplicationContext類型的依賴項(xiàng)解析為Bean所在的ApplicationContext實(shí)例。注意~在普通的BeanFactory中沒有注冊這樣的默認(rèn)類型,甚至連BeanFactory接口本身都沒有。
postProcessBeanFactory使用示例
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
// TODO: 2018/6/7 覆蓋屬性值
System.out.println("BeanFactoryPostProcessor調(diào)用postProcessBeanFactory方法");
BeanDefinition bd = configurableListableBeanFactory.getBeanDefinition("person");
bd.getPropertyValues().addPropertyValue("phone", "110");
// TODO: 2018/6/7 快速初始化bean
configurableListableBeanFactory.preInstantiateSingletons();
}
BeanPostProcessor接口
允許自定義修改新bean實(shí)例的Factory hook,例如檢查標(biāo)記接口或者把bean包裝成代理。
ApplicationContext 可以在它們的beans definitions自動(dòng)檢測BeanPostProcessor bean并且把這些bean應(yīng)用于隨后的bean創(chuàng)建。普通的bean factory允許對后處理器進(jìn)行程序化注冊,通過工廠應(yīng)用于所有bean創(chuàng)建。
BeanPostProcessor 的方法
postProcessBeforeInitialization(Object bean, String beanName):在一些bean實(shí)例化回調(diào)(例如InitializingBean的afterPropertiesSet 或者一個(gè)定制的init-method)之前應(yīng)用這個(gè)BeanPostProcessor
postProcessAfterInitialization(Object bean, String beanName):在一些bean實(shí)例化回調(diào)(例如InitializingBean的afterPropertiesSet 或者一個(gè)定制的init-method)之后應(yīng)用這個(gè)BeanPostProcessor
BeanPostProcessor用法示例
class BeanValidationPostProcessor...
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!this.afterInitialization) {
doValidate(bean);
}
return bean;
}
/**
* Perform validation of the given bean.
* @param bean the bean instance to validate
* @see javax.validation.Validator#validate
*/
protected void doValidate(Object bean) {
Set<ConstraintViolation<Object>> result = this.validator.validate(bean);
if (!result.isEmpty()) {
StringBuilder sb = new StringBuilder("Bean state is invalid: ");
for (Iterator<ConstraintViolation<Object>> it = result.iterator(); it.hasNext();) {
ConstraintViolation<Object> violation = it.next();
sb.append(violation.getPropertyPath()).append(" - ").append(violation.getMessage());
if (it.hasNext()) {
sb.append("; ");
}
}
throw new BeanInitializationException(sb.toString());
}
}
檢驗(yàn)bean狀態(tài)是否有效。
postProcessBeforeInitialization二
class ApplicationContextAwareProcessor...
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
判斷bean是什么接口,然后進(jìn)行set屬性。應(yīng)該就是api里面說的檢查標(biāo)記接口。
大概意識是bean已經(jīng)實(shí)例成功,你可以做一些校驗(yàn)或者補(bǔ)充些內(nèi)容或者把bean包裝代理注入。包裝代理直接把代理實(shí)例返回就行。
postProcessAfterInitialization和postProcessBeforeInitialization類似。
InstantiationAwareBeanPostProcessorAdapter
實(shí)現(xiàn)SmartInstantiationAwareBeanPostProcessor全部方法的適配器,這將不改變由容器正常處理每一個(gè)實(shí)例化的bean。子類僅覆蓋自己想要的方法。
注意,只有在實(shí)際需要 InstantiationAwareBeanPostProcessor 功能時(shí),才推薦這個(gè)基類。如果您所需要的只是簡單的BeanPostProcessor功能,那么您應(yīng)該選擇直接實(shí)現(xiàn)那個(gè)(更簡單的)接口。
postProcessBeforeInstantiation(Class<?> beanClass, String beanName):在實(shí)例化目標(biāo)bean之前應(yīng)用此BeanPostProcessor。這個(gè)返回的bean也許是一個(gè)代理代替目標(biāo)bean,有效地抑制目標(biāo)bean的默認(rèn)實(shí)例化。如果此方法返回一個(gè)非空對象,則bean的創(chuàng)建過程將被短路。唯一的進(jìn)一步處理被應(yīng)用是BeanPostProcessor.postProcessAfterInitialization(java.lang.Object, java.lang.String)方法(可以自己試下,改變了bean的生命周期實(shí)例化之后直接進(jìn)入BeanPostProcessor.postProcessAfterInitialization)回調(diào)來自于配置好的BeanPostProcessors。這個(gè)回調(diào)將僅被應(yīng)用于有bean class的bean defintions。特別是,它不會(huì)應(yīng)用于采用”factory-method“的beans。后處理器可以實(shí)現(xiàn)擴(kuò)展的SmartInstantiationAwareBeanPostProcessor接口,以便預(yù)測它們將返回的bean對象的類型。
postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName):在工廠將給定的屬性值應(yīng)用到給定的bean之前,對給定的屬性值進(jìn)行后處理。允許檢查全部依賴是否已經(jīng)全部滿足,例如基于一個(gè)@Required在bean屬性的setter上。還允許替換要應(yīng)用的屬性值,通常通過基于原始的PropertyValues創(chuàng)建一個(gè)新的MutablePropertyValues實(shí)例,添加或刪除特定的值。
postProcessAfterInitialization(Object bean, String beanName):在bean初始化回調(diào)(例如:InitializingBean的afterPropertiesSet或者定制的init-method)之后,應(yīng)用這個(gè)BeanPostProcessor去給一個(gè)新的bean實(shí)例。bean已經(jīng)配置了屬性值,返回的bean實(shí)例可能已經(jīng)被包裝。
如果是FactoryBean,這個(gè)回調(diào)將為FactoryBean實(shí)例和其他被FactoryBean創(chuàng)建的對象所調(diào)用。這個(gè)post-processor可以通過相應(yīng)的FactoryBean實(shí)例去檢查決定是否應(yīng)用FactoryBean或者被創(chuàng)建的對象或者兩個(gè)都有。
這個(gè)回調(diào)在一個(gè)由InstantiationAwareBeanPostProcessor短路的觸發(fā)之后將被調(diào)用。
看到這里我也沒看懂是啥意思,下面我們看看源代碼。
postProcessBeforeInstantiation使用示例
class AbstractAutoProxyCreator...
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = this.getCacheKey(beanClass, beanName);
if(beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if(this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if(this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
if(beanName != null) {
TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
if(targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
這個(gè)可以返回代理。
postProcessPropertyValues使用示例
示例一
class RequiredAnnotationBeanPostProcessor ...
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
if (!this.validatedBeanNames.contains(beanName)) {
if (!shouldSkip(this.beanFactory, beanName)) {
List<String> invalidProperties = new ArrayList<String>();
for (PropertyDescriptor pd : pds) {
if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
invalidProperties.add(pd.getName());
}
}
if (!invalidProperties.isEmpty()) {
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
}
}
this.validatedBeanNames.add(beanName);
}
return pvs;
}
這個(gè)方法很明顯校驗(yàn)需要注入的屬性是否有屬性值。
示例二
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
if (bean instanceof EnhancedConfiguration) {
((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
}
return pvs;
}
在AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法試圖自auto-wire其他配置bean之前注入BeanFactory。
postProcessAfterInitialization使用示例
public Object postProcessAfterInitialization(Object bean, String beanName) {
if(bean instanceof AopInfrastructureBean) {
return bean;
} else {
if(bean instanceof Advised) {
Advised advised = (Advised)bean;
if(!advised.isFrozen() && this.isEligible(AopUtils.getTargetClass(bean))) {
if(this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
} else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
if(this.isEligible(bean, beanName)) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
proxyFactory.setTarget(bean);
if(!proxyFactory.isProxyTargetClass()) {
this.evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
return proxyFactory.getProxy(this.getProxyClassLoader());
} else {
return bean;
}
}
}
如果bean是一個(gè)基礎(chǔ)的aop bean那么就直接返回,如果不是基礎(chǔ)的aop bean并且實(shí)現(xiàn)了Advise接口那么就對這個(gè)bean進(jìn)行一些操作,如果不是基礎(chǔ)的aop bean沒實(shí)現(xiàn)Advise接口并且是合格的bean就用代理工廠進(jìn)行代理,如果不是基礎(chǔ)的aop bean沒實(shí)現(xiàn)Advise接口并且不是合格的bean那么也直接返回。
總之對已經(jīng)實(shí)例化的bean進(jìn)行一些處理,可能這個(gè)bean在早期已經(jīng)實(shí)例化了又是單例,那么就銷毀這個(gè)bean用原來的bean。
BeanNameAware接口
接口是被實(shí)現(xiàn)由那些想知道其在bean factory中的名稱的bean實(shí)現(xiàn)。請注意,通常不建議對象依賴于它的bean名稱,因?yàn)檫@表示對外部配置的潛在脆弱依賴性,以及對Spring API可能不必要的依賴。
setBeanName(String name):在創(chuàng)建這個(gè)bean的bean factory里設(shè)置名字。在填充正常bean屬性之后調(diào)用但是在初始化回調(diào)之前例如InitializingBean的afterPropertiesSet方法或者一個(gè)定制的init-method.
示例
class SchedulerFactoryBean ...
public void setBeanName(String name) {
if(this.schedulerName == null) {
this.schedulerName = name;
}
}
對工廠bean進(jìn)行set name
BeanFactoryAware接口
接口由希望知道其擁有的BeanFactory的bean實(shí)現(xiàn)。
例如beans可以通過這個(gè)工廠去查閱和它合作的beans(查閱依賴)。注意大部分beans將選擇通過協(xié)作相應(yīng)bean屬性或者構(gòu)造函數(shù)參數(shù)(依賴注入)去接收協(xié)作beans的引用。
setBeanFactory(BeanFactory beanFactory) :為bean實(shí)例提供所屬工廠的回調(diào)。在普通的bean屬性值填充之后但是在初始化回調(diào)之前(例如InitializingBean的afterPropertiesSet方法或者一個(gè)定制的init-method方法)被調(diào)用
setBeanFactory示例
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if(!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalStateException("Cannot use AdvisorAutoProxyCreator without a ConfigurableListableBeanFactory");
} else {
this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
}
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper = new AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
獲得所屬的beanFactory并拷貝到本對象中??梢酝ㄟ^這個(gè)bean所屬的beanFactory檢查bean依賴的bean、beanClassLoader、互斥的單例等。
InitializingBean接口
接口被實(shí)現(xiàn)由那些需要響應(yīng)所有已經(jīng)被BeanFactory set的屬性:例如執(zhí)行自定義初始化或者僅檢查是否已經(jīng)set所有必要屬性。
實(shí)現(xiàn)InitializingBean的另一種方法是指定一個(gè)自定義的init-method,例如在一個(gè)XML配置文件中指定bean的init-method。
afterPropertiesSet():在設(shè)置完所有提供的bean屬性(并滿足BeanFactoryAware和ApplicationContextAware)之后由beanFactory調(diào)用。這個(gè)方法允許bean實(shí)例只有在所有的bean屬性都被設(shè)置并且在錯(cuò)誤配置的情況下拋出異常的情況下才能執(zhí)行初始化。
afterPropertiesSet示例
public void afterPropertiesSet() {
if(this.getDataSource() == null) {
throw new IllegalArgumentException("Property 'dataSource' is required");
}
}
檢查是否已經(jīng)set所有必要屬性。
/**
* Eagerly create the singleton instance, if necessary.
*/
@Override
public void afterPropertiesSet() throws Exception {
if (isSingleton()) {
this.initialized = true;
this.singletonInstance = createInstance();
this.earlySingletonInstance = null;
}
}
這里沒做什么自定義初始化和檢查是否已經(jīng)set所有必要屬性,而是提前初始化單例bean,說明你可以做一些其他操作。
DisposableBean接口
接口已經(jīng)被實(shí)現(xiàn)由那些想在銷毀釋放資源的bean。如果BeanFactory處理緩存的單例對象,那么它應(yīng)該調(diào)用destroy方法。
應(yīng)用程序上下文在關(guān)閉的時(shí)候應(yīng)該處理它的所有單例。
實(shí)現(xiàn)InitializingBean的另一種方法是指定一個(gè)自定義的destroy-method,例如在一個(gè)XML配置文件中指定bean的destroy-method。
destroy示例
@Override
public void destroy() {
close();
}
/**
* Close this application context, destroying all beans in its bean factory.
* <p>Delegates to {@code doClose()} for the actual closing procedure.
* Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
* @see #doClose()
* @see #registerShutdownHook()
*/
@Override
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
// If we registered a JVM shutdown hook, we don't need it anymore now:
// We've already explicitly closed the context.
if (this.shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
}
catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
/**
* Actually performs context closing: publishes a ContextClosedEvent and
* destroys the singletons in the bean factory of this application context.
* <p>Called by both {@code close()} and a JVM shutdown hook, if any.
* @see org.springframework.context.event.ContextClosedEvent
* @see #destroyBeans()
* @see #close()
* @see #registerShutdownHook()
*/
protected void doClose() {
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isInfoEnabled()) {
logger.info("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
try {
getLifecycleProcessor().onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
// Destroy all cached singletons in the context's BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
this.active.set(false);
}
}
執(zhí)行上下文關(guān)閉:發(fā)布一個(gè)ContextClosedEvent和破壞了這個(gè)應(yīng)用上下文的bean工廠中的單例。
————————————————
版權(quán)聲明:本文為CSDN博主「qq_23473123」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:
https://blog.csdn.net/qq_23473123/article/details/76610052
鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布
??????
??長按上方微信二維碼 2 秒
感謝點(diǎn)贊支持下哈 
