菜瓜:水稻,上次說Bean的LifeCycle,還沒講完java
水稻:啥?說人話?web
菜瓜:spring,bean,生命週期spring
水稻:哦哦,下次直接說人話。說正事,先從BeanFactory、ApplicationContext和FactoryBean開始提及吧緩存
菜瓜:嗯。。陷入沉思。。(欲言又止)app
水稻:講理論不給代碼就是耍流氓ide
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@20d3d15apost
菜瓜:懂了,BeanFactory是Spring的核心--容器,ApplicationContext則是包裹容器的上下文,豐富容器的功能(資源加載,事件驅動等)。FactoryBean也是Spring擴展性的提現測試
水稻:WC,你這個總結提到了精髓。就是擴展性:若是BeanFactory是核心思想,那麼其餘的上下文,後置處理器,仍是Aware接口等等,都是爲了實現擴展this
菜瓜:鋪墊說完了,開始生命週期唄spa
水稻:此次我們反過來先看源碼,再看實驗,再總結
* @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 {
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初始化完成以後的接口調用。循環依賴的處理在它前面。來來來,繼續剛
菜瓜:剛不了剛不了,你一會兒搞這麼多玩意給我看,我哪看得完
水稻:您歇着,下次您何時想了解我再給您說
總結