【Spring】Bean的LifeCycle(生命周期)
菜瓜:水稻,上次說Bean的LifeCycle,還沒講完
水稻:啥?說人話?
菜瓜:spring,bean,生命周期
水稻:。。。那你真的是很棒棒哦!。。。bean生命周期的話,從BeanFactory、ApplicationContext和FactoryBean開始說起
我們知道(你不一定知道)BeanFactory是Spring訪問Bean容器的根接口,源碼的注釋: “The root interface for accessing a Spring bean container.”
而ApplicationContext繼承自BeanFactory,也就是說它具有BeanFactory的屬性和方法,并進一步完善(繼承其他的接口)
FactoryBean跟前兩個關系就不怎么大了,它是spring提供給用戶創建bean的口子,有一些bean創建過程復雜,或者依賴第三方包等(Mybatis-Spring中),可交給用戶自己創建
菜瓜:嗯。。陷入沉思。。(欲言又止)
水稻:講理論不給代碼就是耍流氓
package com.vip.qc.postprocessor;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
/**
* @author QuCheng on 2020/6/15.
*/
@Component("fb")
public class FactoryBeanT implements FactoryBean<FactoryBeanT.CustomBean> {
public FactoryBeanT() {
System.out.println("實現FactoryBean接口的類自身被放在IOC一級緩存的容器里面,getObject的對象是在另一個緩存對象中");
}
@Override
public CustomBean getObject() {
return new CustomBean();
}
@Override
public Class<?> getObjectType() {
return CustomBean.class;
}
static class CustomBean {
public CustomBean() {
System.out.println("自定義bean");
}
}
}
測試方法
@Test
public void testTransa() {
BeanFactory context = new AnnotationConfigApplicationContext(ComponentScanD.class);
System.out.println("factoryBean : " + context.getBean("fb"));
System.out.println("&factoryBean : " + context.getBean("&fb"));
}
測試結果
實現FactoryBean接口的類自身被放在IOC一級緩存的容器里面,getObject的對象是在另一個緩存對象中
自定義bean
factoryBean : com.vip.qc.postprocessor.FactoryBeanT$CustomBean@214b199c
&factoryBean : com.vip.qc.postprocessor.FactoryBeanT@20d3d15a
菜瓜:懂了,BeanFactory是Spring的核心--容器,ApplicationContext則是包裹容器的上下文,豐富容器的功能(資源加載,事件驅動等)。FactoryBean也是Spring擴展性的體現
水稻:WC,你這個總結提到了精髓。就是擴展性:如果BeanFactory是核心思想,那么其他的上下文,后置處理器,還是Aware接口等等,都是為了實現擴展
菜瓜:鋪墊說完了,開始生命周期唄
水稻:這次咱們反過來先看源碼,再看實驗,再總結
BeanFactory源碼注釋 - 定義了實現的生命周期
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @since 13 April 2001
* @see BeanNameAware#setBeanName
* @see BeanClassLoaderAware#setBeanClassLoader
* @see BeanFactoryAware#setBeanFactory
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader
* @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
* @see org.springframework.context.MessageSourceAware#setMessageSource
* @see org.springframework.context.ApplicationContextAware#setApplicationContext
* @see org.springframework.web.context.ServletContextAware#setServletContext
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
* @see InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
* @see DisposableBean#destroy
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
*/
public interface BeanFactory {
BeanFactory源碼實現類
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// BeanNameAware BeanFactoryAware ...
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor Before @PostConstruct
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// initMethod InitializingBean接口
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor after
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
實驗代碼
package com.vip.qc.postprocessor;
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;
import org.springframework.stereotype.Component;
/**
* @author QuCheng on 2020/6/14.
*/
@Component
public class BeanFactoryPostProcessorT implements BeanFactoryPostProcessor {
public static final String BEAN_NAME = "initializingBeanT";
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition initializingBeanT = beanFactory.getBeanDefinition(BEAN_NAME);
System.out.println("BeanFactoryPostProcessor bean " + initializingBeanT.getBeanClassName());
}
}
package com.vip.qc.postprocessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* @author QuCheng on 2020/6/14.
*/
@Component
public class BeanPostProcessorT implements BeanPostProcessor {
public static final String BEAN_NAMET = "initializingBeanT";
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (BEAN_NAMET.equals(beanName)) {
InitializingBeanT processorT = ((InitializingBeanT) bean);
System.out.println("BeanPostProcessor BeforeInitialization " + processorT);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (BEAN_NAMET.equals(beanName)){
InitializingBeanT processorT = ((InitializingBeanT) bean);
System.out.println("BeanPostProcessor AfterInitialization " + processorT);
}
return bean;
}
}
package com.vip.qc.postprocessor;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author QuCheng on 2020/6/14.
*/
@Component
public class InitializingBeanT implements BeanNameAware, InitializingBean, DisposableBean {
public InitializingBeanT() {
System.out.println("init無參構造 execute");
}
@PostConstruct
public void postConstruct() {
System.out.println("@PostConstruct execute");
}
@PreDestroy
public void preDestroy() {
System.out.println("@PreDestroy execute");
}
@Override
public void afterPropertiesSet() {
System.out.println("InitializingBean afterPropertiesSet --> " + this.toString());
}
@Override
public void setBeanName(String name) {
System.out.println("BeanNameAware : " + name);
}
@Override
public void destroy() {
System.out.println("destroy");
}
}
測試代碼
@Test
public void testLifeCycle() {
AbstractApplicationContext applicationContext = new AnnotationConfigApplicationContext(ComponentScanD.class);
applicationContext.close();// 這里不關閉容器的話,注銷bean的方法會看不到打印
}
測試結果
BeanFactoryPostProcessor bean com.vip.qc.postprocessor.InitializingBeanT
init無參構造 execute
BeanNameAware : initializingBeanT
BeanPostProcessor BeforeInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
@PostConstruct execute
InitializingBean afterPropertiesSet --> com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
BeanPostProcessor AfterInitialization com.vip.qc.postprocessor.InitializingBeanT@15bb6bea
@PreDestroy execute
destroy
菜瓜:實現什么的不重要,接口才是爸爸呀,BeanFactory定義好了生命周期,下面的實現也只是實現罷了
水稻:哈哈,你說的對,一流的公司賣標準
菜瓜:這里怎么沒看到循環依賴的處理啊
水稻:是的。這里的源碼我只截取了bean初始化完成之后的接口調用。循環依賴的處理在它前面。來來來,繼續剛
菜瓜:剛不了剛不了,你一下子搞這么多玩意給我看,我哪看得完
水稻:您歇著,下次您什么時候想了解我再給您說
總結
BeanFactory已經定義了整個的生命周期,子類只是負責實現,demo演示也只是為了證實。我們更應該關注更上層的東西
ApplicationContext是對容器更精細化的包裝,提供了更完善的功能
FactoryBean是Spring擴展性的提現,可供用戶自己定義創建bean。擴展性提煉的很好
總結
以上是生活随笔為你收集整理的【Spring】Bean的LifeCycle(生命周期)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在 SAP BTP ABAP 编程环
- 下一篇: 牧羊人之心黑山羊的幼崽怎么获得 黑山羊的