Spring 源碼解析
- 第一章為源碼解析。
- 第二章為實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 IOC 容器蚊荣。
- 第三章進(jìn)階 Spring 插件開發(fā)。
概念
Spring 源碼的核心組件:
- IOC 容器負(fù)責(zé)實(shí)例化,定位,配置應(yīng)用程序中的對(duì)象及建立這些對(duì)象間的依賴油坝。
- AOP 面向切面編程,通過預(yù)編譯方式和運(yùn)行期間動(dòng)態(tài)代理實(shí)現(xiàn)功能的統(tǒng)一維護(hù)的一種技術(shù)刨裆。
IOC 容器可以理解為一個(gè) Map澈圈,key 就是我們平常使用 Spring 框架時(shí)寫的 Bean Id,value 就是對(duì)應(yīng)類的實(shí)例化對(duì)象帆啃。
幾個(gè)重要的類
在開始分析源碼之前瞬女,我們先試著了解幾個(gè)概念,這幾個(gè)類對(duì)于我們理解源碼有著很大的幫助努潘,方便對(duì)整個(gè) Spring 源碼進(jìn)行分析诽偷。
-
ApplicationContext,BeanFactory
提到 Spring 就一直說容器疯坤,這個(gè)容器我們上面也給出了一個(gè)直觀的解釋报慕,可以理解為一個(gè) Map,用來存儲(chǔ)實(shí)例化的的對(duì)象压怠,需要的時(shí)候就從容器里面取就可以了眠冈。那么在代碼中的具體實(shí)現(xiàn)是什么那?大家最為熟悉的實(shí)現(xiàn)可能就是 ApplicationContext菌瘫,它就是一個(gè)容器蜗顽,而它實(shí)現(xiàn)了 BeanFactory 接口,可以說 BeanFactory 就是最基礎(chǔ)的容器雨让,ApplicationContext 相當(dāng)于在 BeanFactory 接口增加了一些功能雇盖,它們都可以稱為容器。
先來看看 BeanFactory 的代碼:
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String var1) throws BeansException; <T> T getBean(String var1, @Nullable Class<T> var2) throws BeansException; Object getBean(String var1, Object... var2) throws BeansException; <T> T getBean(Class<T> var1) throws BeansException; <T> T getBean(Class<T> var1, Object... var2) throws BeansException; boolean containsBean(String var1); boolean isSingleton(String var1) throws NoSuchBeanDefinitionException; boolean isPrototype(String var1) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String var1, @Nullable Class<?> var2) throws NoSuchBeanDefinitionException; @Nullable Class<?> getType(String var1) throws NoSuchBeanDefinitionException; String[] getAliases(String var1); }
整個(gè)接口定義的抽象方法其實(shí)非常簡(jiǎn)單和直接,主要就是各種個(gè)樣的 getBean 方法和一些判斷是否是單例或者原型的方法栖忠。
再來看 ApplicationContext崔挖。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver { @Nullable String getId(); String getApplicationName(); String getDisplayName(); long getStartupDate(); @Nullable ApplicationContext getParent(); AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException; }
不僅僅實(shí)現(xiàn)了 BeanFactory 接口贸街,而且實(shí)現(xiàn)了事件派發(fā)器,資源解析器以及環(huán)境參數(shù)相關(guān)的接口狸相,比 BeanFactory 多了許多功能匾浪。
下面來看看常用的容器,也就是上面接口的實(shí)現(xiàn)類卷哩。
- AnnotationConfigApplicationContext
基于 @Configuration 注解配置類解析的容器蛋辈。 - ClassPathXmlApplicationContext
基于類路徑下 xml 文件配置解析的容器,如果用 xml 方式配置 Spring 框架,這個(gè)容器一定使用的非常多。 - FileSystemXmlApplicationContext
基于文件系統(tǒng)里的 xml 文件配置解析的容器舔示。 - GenericApplicationContext
不太常用的 ApplicationContext,比上面兩個(gè)更加靈活逞频,可以讀取任意配置方式的 Bean。
- AnnotationConfigApplicationContext
-
BeanDefinition
BeanDefinition 按照字面意思理解就是 Bean 的定義信息栋齿,我們從接口的定義來看看這個(gè)類到底保存了什么信息苗胀。public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { String SCOPE_SINGLETON = "singleton"; String SCOPE_PROTOTYPE = "prototype"; int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; void setParentName(@Nullable String var1); @Nullable String getParentName(); void setBeanClassName(@Nullable String var1); @Nullable String getBeanClassName(); void setScope(@Nullable String var1); @Nullable String getScope(); void setLazyInit(boolean var1); boolean isLazyInit(); void setDependsOn(@Nullable String... var1); @Nullable String[] getDependsOn(); void setAutowireCandidate(boolean var1); boolean isAutowireCandidate(); void setPrimary(boolean var1); boolean isPrimary(); void setFactoryBeanName(@Nullable String var1); @Nullable String getFactoryBeanName(); void setFactoryMethodName(@Nullable String var1); @Nullable String getFactoryMethodName(); ConstructorArgumentValues getConstructorArgumentValues(); default boolean hasConstructorArgumentValues() { return !this.getConstructorArgumentValues().isEmpty(); } MutablePropertyValues getPropertyValues(); default boolean hasPropertyValues() { return !this.getPropertyValues().isEmpty(); } boolean isSingleton(); boolean isPrototype(); boolean isAbstract(); int getRole(); @Nullable String getDescription(); @Nullable String getResourceDescription(); @Nullable BeanDefinition getOriginatingBeanDefinition(); }
從代碼里看,BeanDefintion 里面保存了 Bean 的 Class 類名稱瓦堵,作用域【單例或者原型】基协,構(gòu)造函數(shù)的參數(shù),屬性等等菇用,這些信息也說明這個(gè)類是 Spring 用來構(gòu)建 Bean 的主要的類澜驮。
這個(gè)接口的主要實(shí)現(xiàn)類有 RootBeanDefinition,ChildBeanDefinition惋鸥,GenericBeanDefinition等等杂穷。其中 RootBeanDefinition 最為常用,相當(dāng)于 xml 文件中的 <bean> 標(biāo)簽卦绣,在 xml 中可以配置 parent 屬性耐量,這里的父就是 RootBeanDefinition,子就是 ChildBeanDefinition滤港。
-
BeanDefinitionRegistry
既然有了材料 BeanDefinition廊蜒,下面一定需要一個(gè)操作它的類,BeanDefinitionRegistry 就是一個(gè)用來幫我們操作 BeanDefinition 的接口蜗搔,它的里面有許多操作 BeanDefinition 的方法劲藐,包括通過 BeanDefinition 注冊(cè) Bean 等等八堡。public interface BeanDefinitionRegistry extends AliasRegistry { void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException; void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException; BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException; boolean containsBeanDefinition(String var1); String[] getBeanDefinitionNames(); int getBeanDefinitionCount(); boolean isBeanNameInUse(String var1); }
我們可以通過 registerBeanDefinition 方法將一個(gè) Bean 注冊(cè)到容器中樟凄。調(diào)用 BeanDefinitionRegistry.registerBeanDefinition 手工進(jìn)行注冊(cè)。
BeanDefinitionRegistry registry = context.getRegistry(); boolean definition = registry.containsBeanDefinition("person");
-
BeanPostProcessor
BeanPostProcessor兄渺,bean 的后置處理器缝龄,在 bean 初始化前后進(jìn)行一些處理工作。postProcessBeforeInitialization:在初始化之前
工作。postPorcessAfterInitialization:在初始化之后工作叔壤。public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
由此衍生出來的后置處理器非常多瞎饲,處理時(shí)機(jī)也不一樣,我們會(huì)在后面的源碼分析對(duì)這些后置處理器的實(shí)現(xiàn)原理和操作時(shí)機(jī)進(jìn)行一個(gè)總結(jié)炼绘。
Spring 底層對(duì) BeanPostProcessor 的使用:bean 賦值嗅战,注入其他組件,@Autowired俺亮,聲明周期注解功能驮捍,@Async等等。 -
ApplicationContextAware
自定義組件想要使用 Spring 容器底層的一些組件(ApplicationContext脚曾,BeanFactory东且,xxx)等等,需要自定義組件實(shí)現(xiàn) xxxAware 接口本讥。在創(chuàng)建對(duì)象的時(shí)候珊泳,會(huì)調(diào)用接口規(guī)定的方法注入相關(guān)組件。ApplicationContextAware 會(huì)將 IOC 容器傳入到組件中拷沸,BeanNameAware 會(huì)講當(dāng)前實(shí)例在 IOC 容器中 Bean 的名字傳入到實(shí)例中色查。這些 Aware 會(huì)有對(duì)應(yīng)的 AwareProcessor 來進(jìn)行邏輯處理。public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext var1) throws BeansException; }
如果想往組件中注入容器可以實(shí)現(xiàn) ApplicationContextAware 接口撞芍,然后通過 setApplicationContext 保存起來综慎。 我們對(duì) Spring 功能進(jìn)行擴(kuò)展時(shí)常常喲昂到這些 Aware。
ApplicationListener 與 ApplicationEventMulticaster
這兩個(gè)組件是 Spring 事件驅(qū)動(dòng)模型用到的組件勤庐,ApplicationListener:事件監(jiān)聽示惊。ApplicationEventMulticaster:事件派發(fā)。
Bean 的生命周期
Bean 的聲明周期指的是 Bean 的創(chuàng)建-->初始化-->銷毀的過程愉镰,Spring 把這個(gè)過程全部交給容器來管理米罚。我們可以自定義初始化和銷毀方法,容器在 Bean 進(jìn)行到當(dāng)前生命周期的時(shí)候來調(diào)用我們自定一的初始化和銷毀方法丈探。
構(gòu)造(對(duì)象創(chuàng)建)
單實(shí)例:在容器啟動(dòng)的時(shí)候創(chuàng)建對(duì)象录择。
多實(shí)例:在每次獲取的時(shí)候創(chuàng)建對(duì)象,調(diào)用 getBean 方法時(shí)碗降。
初始化
對(duì)象創(chuàng)建完成隘竭,并賦值好,調(diào)用初始化方法
銷毀
單實(shí)例:容器關(guān)閉的時(shí)候讼渊。
多實(shí)例:容器會(huì)創(chuàng)建 Bean动看, 但不會(huì)管理 Bean,容器不會(huì)調(diào)用銷毀方法爪幻。
Bean 的生命周期要比上面寫的更加復(fù)雜菱皆,我們?cè)诜治鐾暝创a后會(huì)對(duì)這部分進(jìn)行一個(gè)總結(jié)须误。
幾個(gè)重要的注解
@Import,快速給容器中導(dǎo)入一個(gè)組件仇轻,@Import(Color.class) 相當(dāng)于一個(gè)無參構(gòu)造函數(shù)京痢。id 默認(rèn)是全類名。
@Conditional 滿足一定條件才給容器中注冊(cè)bean篷店,這個(gè)可以用來讓兩個(gè)bean形成依賴祭椰,可以用在方法上,也可以用在類上疲陕。這個(gè)注解在 SpringBoot 用的非常多吭产。
最后說說 @Autowired 和 @Resource 的區(qū)別:
@Autowired 自動(dòng)注入默認(rèn)按照 type 注入,即按照 .class 查找鸭轮。如果找到多個(gè)相同類型的組件臣淤,在將屬性的名稱作為組件的 id 去容器中查找。使用 @Qualifier("bookDao") 與 @Autowired 組合可以明確指定需要裝配的 Bean窃爷,通過 id邑蒋。
@Autowired(require=false) 有就裝配,沒有就變?yōu)?null按厘。
Spring 還支持 JSR250 和 JSR330 里的 @Resource 和 @Inject 注解医吊。Java 規(guī)范的注解。@Resource 和 @Autowired 一樣實(shí)現(xiàn)自動(dòng)裝配逮京,默認(rèn)按照屬性名稱進(jìn)行自動(dòng)裝配卿堂。不支持 @Primary,也不支持 @Autowired(require=false)懒棉。
@Inject 需要額外導(dǎo)入包草描,功能和 @Autowired 一樣,不支持 require=false策严;
@Autowired 可以標(biāo)注在構(gòu)造器穗慕、參數(shù)、方法妻导、屬性上逛绵。
提出問題
有了一些概念后,我們心里一定會(huì)有一些問題倔韭,同時(shí)帶著問題去看源碼也有助于我們更加快速地切入到 Spring 得核心术浪,不墨跡,直給寿酌。
- 容器時(shí)怎么創(chuàng)建得胰苏,創(chuàng)建時(shí)都要做哪些工作。
- Spring 為什么要用 BeanDefintion 去構(gòu)造 Bean份名。
- Spring 用 BeanDefintion 去構(gòu)建 Bean 得流程是什么碟联?
- Spring AOP 在 Spring 框架得基礎(chǔ)上做了什么妓美?
下面我們帶著問題去看看源碼僵腺。
容器創(chuàng)建和初始化過程
還是從下面這段代碼開始
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
new 容器的過程到底執(zhí)行了什么操作那鲤孵?前兩步是預(yù)處理和配置類的解析工作,我們直接看 refresh 方法辰如,這個(gè)方法就是容器的創(chuàng)建和刷新以及 Bean 初始化的核心方法普监。
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
refresh() 核心方法:
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
- prepareRefresh() 刷新前的預(yù)處理
- initPropertySources,字面上理解就是初始化一些屬性琉兜,但是方法體是空的凯正,留給子類去實(shí)現(xiàn)。子類可以自定義個(gè)性化屬性設(shè)置方法豌蟋。
- getEnvironment().validateRequiredProperties()廊散,屬性校驗(yàn)。
- earlyApplicationEvents梧疲,用來保存容器中的一些早期的事件允睹。等事件派發(fā)器初始化好了之后再把它們派發(fā)出去。
- obtainFreshBeanFactory() 獲取 Bean 工廠幌氮。
-
refreshBeanFactory()缭受,刷新【創(chuàng)建】 BeanFactory。
在 GenericApplicationContext 里無參構(gòu)造器創(chuàng)建一個(gè) BeanFactory 對(duì)象该互。
this.beanFactory = new DefaultListableBeanFactory();
設(shè)置一個(gè) Id米者。
getBeanFactory(),返回剛才 GenericApplicationContext 創(chuàng)建的 BeanFactory 對(duì)象宇智。剛創(chuàng)建蔓搞,里面都是默認(rèn)的配置。
將創(chuàng)建的 BeanFactory【DefaultListableBeanFactory】返回随橘。
- prepareBeanFactory()败明,BeanFactory 的預(yù)準(zhǔn)備工作,BeanFactory 進(jìn)行一些設(shè)置太防。
設(shè)置 BeanFactory 的類加載器妻顶、支持表達(dá)式解析器。蜒车。讳嘱。
添加 部分的BeanPostProcessor【ApplicationContextAwareProcessor】
設(shè)置忽略自動(dòng)裝配的接口,EnvironmentAware酿愧、EmbeddedValueResolverAware沥潭。。嬉挡。
注冊(cè)可以解析的自動(dòng)裝配钝鸽,我們可以在任何組件中自動(dòng)注入汇恤,ResourceLoader,BeanFactory拔恰,ApplicationContext因谎。
添加 BeanPostProcessor【ApplicationListenerDetector】。
添加編譯時(shí)的 AspectJ颜懊。
-
給 BeanFactory 中注冊(cè)一些能用的組件财岔。
environment
systemProperties
systemEnvironment
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(this.getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
if (beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
if (!beanFactory.containsLocalBean("environment")) {
beanFactory.registerSingleton("environment", this.getEnvironment());
}
if (!beanFactory.containsLocalBean("systemProperties")) {
beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean("systemEnvironment")) {
beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}
}
- postProcessBeanFactory,BeanFactory 準(zhǔn)備工作完成后進(jìn)行的后置處理工作河爹,子類通過重寫這個(gè)方法來在 BeanFactory 創(chuàng)建并預(yù)備完成以后做進(jìn)一步的設(shè)置匠璧。
=============================以上是 BeanFactory 創(chuàng)建及準(zhǔn)備================================
- invokeBeanFactoryPostProcessors(beanFactory),執(zhí)行 BeanFactoryPostProcessor咸这。
BeanFactoryProcessor:BeanFactory 的后置處理器夷恍,在 BeanFactory 標(biāo)準(zhǔn)初始化執(zhí)行的 Processor,標(biāo)準(zhǔn)初始化就是以上四部媳维。
兩個(gè)主要接口酿雪,BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor(可以用這個(gè)來注冊(cè)一些新的組件 )侨艾。
執(zhí)行 BeanPostProcessor 的方法:
先執(zhí)行 BeanDefintionRegistryPostProcessor
獲取所有的 BeanDefinitionRegistryPostProcessor执虹。
-
對(duì)于實(shí)現(xiàn)了 PriorityOrdered 優(yōu)先級(jí)接口的 BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
-
對(duì)于實(shí)現(xiàn)了 Ordered 順序接口的 BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
-
最后執(zhí)行沒有實(shí)現(xiàn)任何優(yōu)先級(jí)或者是順序接口的 BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
在執(zhí)行 BeanFactoryPostProcessor 的方法
- 流程和 BeanDefinitionRegistryPostProcessor 一模一樣。
- registerBeanPostProcessors唠梨,注冊(cè) BeanPostProcessor袋励,Bean 的后置處理器【攔截 Bean 的創(chuàng)建過程】。
不同接口類型的 BeanPostProcessor当叭,在 Bean 創(chuàng)建前后的執(zhí)行時(shí)機(jī)是不一樣的茬故。
BeanPostProcessor
DestructionAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor【internalPostProcessors】
獲取所有的 BeanPostProcessor,后置處理器都默認(rèn)可以有 PriorityOrdered蚁鳖,Ordered 來指定優(yōu)先級(jí)磺芭。
-
先注冊(cè) PriorityOrdered 優(yōu)先級(jí)接口的 BeanPostProcessor,把每一個(gè) BeanPostProcessor 添加到 BeanFactory 中醉箕。
beanFactory.addBeanPostProcessor(postProcessor)
再注冊(cè) Ordered 接口的钾腺。
最后注冊(cè)沒有實(shí)現(xiàn)任何優(yōu)先級(jí)接口的。
最終注冊(cè)讥裤,MergedBeanDefinitionPostProcessor放棒。
-
注冊(cè)一個(gè) ApplicationListenerDetector,來在 Bean 創(chuàng)建完成后檢查是否是 ApplicationListener己英,如果是
applicationContext.addApplicationListener((ApplicationListener<?>) bean);
- initMessageSource间螟,初始化 MessageSource 組件,做國(guó)際化消息,消息綁定厢破,消息解析荣瑟。
獲取 BeanFactory。
-
判斷容器有沒有 id 為 messageSource 的摩泪,類型是 MessageSource 的組件
如果有賦值給 messageSource 屬性笆焰,如果沒有自己創(chuàng)建一個(gè) DelegatingMessageSource。
MessageSource 取出國(guó)際化配置文件中的某個(gè) key 值加勤,能按照區(qū)域信息獲取仙辟。
-
把創(chuàng)建好的 MessageSource 注冊(cè)到容器中同波,以后獲取國(guó)際化配置文件的值的時(shí)候鳄梅,可以自動(dòng)注入 MessageSource,調(diào)用 getMessage 方法就可以獲取到了未檩。
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)
- initApplicationEventMulticaster戴尸,初始化事件派發(fā)器。
- 獲取 BeanFactory冤狡。
- 從 BeanFactory 中獲取 ID 為 applicationEventMulticaster孙蒙,類型為 ApplicationEventMulticaster 的派發(fā)器。
- 如果上一步?jīng)]有配置事件派發(fā)器悲雳,就創(chuàng)建一個(gè) SimpleApplicationEventMulticaster挎峦,為我們派發(fā)事件。
- 將創(chuàng)建的 ApplicationEventMulticaster 添加到 BeanFactory 中合瓢,以后其他組件自動(dòng)注入即可坦胶。
onRefresh,留給子容器(子類)晴楔,重寫 onRefresh 方法顿苇,在容器刷新時(shí)可以再自定義邏輯。
registerListeners税弃,給容器中把項(xiàng)目里的 ApplicationListener 注冊(cè)進(jìn)來纪岁。
-
從容器中拿到所有的 ApplicationListener 組件,將每個(gè)監(jiān)聽器添加到事件派發(fā)器中则果。
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)
派發(fā)之前步驟產(chǎn)生的事件幔翰,派發(fā)器沒初始化之前的。
- finishBeanFactoryInitialization西壮,初始化所有剩下的單實(shí)例 Bean遗增。
//初始化所有剩下的單實(shí)例 bean。
beanFactory.preInstantiateSingletons();
獲取容器中的所有 BeanDefinitions茸时,依次進(jìn)行初始化和創(chuàng)建對(duì)象贡定。
-
如果 Bean 不是抽象的,是單實(shí)例可都,不是懶加載的缓待,就開始創(chuàng)建單例 Bean蚓耽。
判斷是否是 FactoryBean,即是否實(shí)現(xiàn)了 FactoryBean 接口的 Bean旋炒,如果是就用工廠方法創(chuàng)建對(duì)象步悠。
如果不是工廠 Bean,利用 getBean(beanName) 創(chuàng)建對(duì)象瘫镇。
getBean(beanName)鼎兽,就是自己寫測(cè)試類的那個(gè) getBean。
調(diào)用 doGetBean(name,null,null,false)铣除。
-
先獲取緩存中保存的單實(shí)例 Bean谚咬,如果能獲取到說明這個(gè) Bean 之前被創(chuàng)建過了(所有創(chuàng)建過的單實(shí)例 Bean 都會(huì)被緩存起來)。
//保存單實(shí)例 Bean 的 private final Map<String,Object> singletonObjects = new ConcurrentHashMap<String,Object>(256);
- 緩存中獲取不到尚粘,開始 Bean 的創(chuàng)建對(duì)象流程择卦。
- 標(biāo)記當(dāng)前 Bean 已經(jīng)被創(chuàng)建。
- 獲取 Bean 的定義信息郎嫁。
- 獲取當(dāng)前 Bean 所依賴的其他 Bean秉继,如果有就按照 getBean() 把依賴的 Bean 先創(chuàng)建出來。
- 啟動(dòng)單實(shí)例 Bean 的創(chuàng)建流程泽铛。
```java
createBean(beanName,mbd,args);
//讓 BeanPostProcessor 攔截返回對(duì)象尚辑。正常的 BeanPostProcessor 是對(duì)象創(chuàng)建完成初始化之前執(zhí)行的,而這個(gè) BeanPostProcessor 要在 Bean 創(chuàng)建之前執(zhí)行
//InstantiationAwareBeanPostProcessor 提前執(zhí)行
//觸發(fā) postProcessBeforeInstantiation 方法
//如果上一步有返回值盔腔,在觸發(fā) postProcessAfterInitialization 方法
Object bean = resolveBeforeInstantiation(beanName,mbdToUse);
```
如果 InstantiationAwareBeanPostProcessor 沒有返回代理對(duì)象杠茬,調(diào)用下面的方法創(chuàng)建 Bean。
```java
Object beanInstance = doCreateBean(beanName,mbcToUse,args);
//創(chuàng)建 Bean 實(shí)例铲觉,利用工廠方法或者對(duì)象的構(gòu)造器創(chuàng)建出 Bean 實(shí)例澈蝙。
createBeanInstance(beanName,mbd,args);
// 創(chuàng)建實(shí)例對(duì)象后,執(zhí)行后置處理器
// 利用 MergedBeanDefintionPostProcessor
applyMergedBeanDefintionPostProcessor(mbd,beanType,beanName);
bdp.postProcessMergedBeanDefinition(mbd,beanType,beanName);
```
對(duì) Bean 的屬性進(jìn)行賦值
```java
populateBean(beanName,mbd,instanceWrapper);
//賦值之前拿到 InstantiationAwareBeanPostProcessor 后置處理器
//執(zhí)行 postProcessAfterInstantiation
//再拿 InstantiationAwareBeanPostProcessor 后置處理器
//執(zhí)行 postProcessPropertyValues 方法
//最后一步撵幽,應(yīng)用 Bean 屬性的值灯荧,利用 setter 方法等用反射賦值。
applyPropertyValues(beanName,mbd,bw,pvs);
```
對(duì) Bean 進(jìn)行初始化
```java
initializeBean(beanName,exposedObject,mbd);
//執(zhí)行 Aware 接口的方法
//判斷是否是 BeanNameAware盐杂,BeanClassLoaderAware逗载,BeanFactoryAware,利用 invoke 回調(diào)接口的方法链烈。
invokeAwareMethods(beanName,bean);
//執(zhí)行所有后置處理器初始化之前的方法
applyBeanPostProcessorsBeforeInitialization(wrapperBean)
//執(zhí)行后置處理器的回調(diào)方法
BeanPostProcessor.postProcessBeforeInitialization()
//執(zhí)行初始化方法
invokeInitMethods(beanName,wrappedBean,mbd);
//是否是 InitializingBean 接口實(shí)現(xiàn)類厉斟,執(zhí)行接口規(guī)定的初始化。
//是否自定義初始化方法强衡。
//執(zhí)行初始化之后后置處理器的方法
applyBeanPostProcessorsAfterInitialization(wrapperBean)
//執(zhí)行后置處理器的回調(diào)方法
BeanPostProcessor.postProcessAfterInitialization()
```
注冊(cè) Bean 的銷毀方法擦秽。不執(zhí)行方法,在容器銷毀時(shí)執(zhí)行。
- ·將創(chuàng)建的 Bean 添加到緩存 singletonObjects 中感挥。IOC 容器就可以理解為這些 Map缩搅,這些 Map 里面保存了很多單實(shí)例 Bean,環(huán)境信息触幼。
- 檢查所有 Bean 是否實(shí)現(xiàn)了 SmartInitializingSingleton 接口硼瓣,如果是,就執(zhí)行回調(diào)方法置谦。
- finishRefresh 完成 BeanFactory 初始化創(chuàng)建工作堂鲤,IOC 容器創(chuàng)建完成。
-
初始化和聲明周期有關(guān)的后置處理器
initLifecycleProcessor()媒峡; //先從容器中找瘟栖,找不到 new 一個(gè) Default 的,并且注冊(cè)在 BeanFactory 中丝蹭,可以注入到組件中慢宗。 //允許寫 LifecycleProcessor坪蚁, 可以在 BeanFactory 刷新完成或者關(guān)閉時(shí)調(diào)用一些方法奔穿。 void onRefresh(); void onClose();
拿到前面定義的生命周期處理器,回調(diào) onRefresh 方法敏晤。
-
發(fā)布容器刷新完成事件贱田。
publishEvent(new ContextRefreshedEvent(this));
總結(jié):
Spring 創(chuàng)建 Bean 的時(shí)機(jī):
- 用到這個(gè) Bean 的時(shí)候,利用 getBean 創(chuàng)建 bean 后保存到容器中嘴脾。
- 同一創(chuàng)建所有剩下的 bean 的時(shí)候男摧,finishBeanFactoryInitialization();
后置處理器:
每一個(gè) Bean 創(chuàng)建完成后,都會(huì)使用各種后置處理器進(jìn)行處理译打,來增強(qiáng) Bean 的功能耗拓。
- AutowiredAnnotationBeanPostProcessor:來處理自動(dòng)注入。
- AnnotationAwareAspectJAutoProxyCreator:來做 AOP 功能奏司。
- AsyncAnnotationBeanPostProcessor:增強(qiáng)功能注解乔询。
AOP原理
整體啟動(dòng)流程:
傳入配置類,創(chuàng)建 IOC 容器韵洋。
注冊(cè)配置類竿刁,調(diào)用 refresh() 刷新容器。
-
registerBeanPostProcessors(beanFacotry)搪缨,注冊(cè) Bean 的后置處理器方便攔截 Bean 的創(chuàng)建食拜。
獲取 IOC 容器中已經(jīng)定義了的需要?jiǎng)?chuàng)建對(duì)象的所有 BeanPostProcessor,配置類里注冊(cè)的副编。
給容器中加其他的 PostProcessor负甸。
優(yōu)先注冊(cè)了實(shí)現(xiàn)了 PriorityOrdered 接口的 BeanPostProcessor。
再給容器中注冊(cè)實(shí)現(xiàn)了 Ordered 接口的 BeanPostProcessor。
最后注冊(cè)沒實(shí)現(xiàn)優(yōu)先級(jí)接口的 BeanPostProcessor呻待。
注冊(cè) BeanPostProcessor煮盼,實(shí)際上就是創(chuàng)建 BeanPostProcessor 的對(duì)象并保存在容器中。
-
創(chuàng)建 internalAutoProxyCreator 的 BeanPostProcessor[AnnotationAwareAspectJAutoProxyCreator]
- 創(chuàng)建 Bean 的實(shí)例
- populateBean:給 Bean 的屬性賦值
- initializeBean:初始化 Bean
- invokeAwareMethods():處理 Aware 接口的方法回調(diào)带污。
- applyBeanPostProcessorsBeforeInitialization():應(yīng)用后置處理器的 postProcessBeforeInitialization 方法僵控。
- invokeInitMethods():執(zhí)行自定義初始化方法。
- applyBeanPostProcessorsAfterInitialization():執(zhí)行后置處理器的 PostProcessAfterInitialization 方法鱼冀。
- BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator) 創(chuàng)建成功报破。調(diào)用 initBeanFactory 生成 aspectJAdvisorsBuilder。
-
把 BeanPostProcessor 注冊(cè)到 BeanFactory 中:
beanFactory.addBeanPostProcessor(postProcessor)千绪。
==========以上是創(chuàng)建和注冊(cè) AnnotationAwareAspectJAutoProxyCreator 的過程=========
AnnotationAwareAspectJAutoProxyCreator 這個(gè) BeanPostProcessor 做了什么充易?
看給容器中注冊(cè)了什么組件,這個(gè)組件什么時(shí)候工作荸型,有什么功能盹靴?
AnnotationAwareAspectJAutoProxyCreator => InstantiationAwareBeanPostProcessor
-
finishBeanFactoryInitialization(beanFactoty),完成 BeanFactory 的初始化工作瑞妇,創(chuàng)建剩下的單實(shí)例 Bean稿静。
- 遍歷獲取容器中所有的 Bean,依次創(chuàng)建對(duì)象 getBean(beanName)辕狰。
getBean->doGetBean()->getSingleton()
-
創(chuàng)建 Bean
【AnnotationAwareAspectJAutoProxyCreator 在所有 Bean 創(chuàng)建之前會(huì)有一個(gè)攔截改备,因?yàn)閷?shí)現(xiàn)了InstantiationAwareBeanPostProcessor,會(huì)調(diào)用 postProcessBeforeInstantiation 方法】
先從緩存中獲取當(dāng)前 Bean蔓倍,如果能獲取到悬钳,說明 Bean 是之前被創(chuàng)建過的,直接使用偶翅,否則再創(chuàng)建默勾。只要?jiǎng)?chuàng)建好的 Bean 都會(huì)被緩存起來。
-
createBean()聚谁,創(chuàng)建 Bean母剥。AnnotationAwareAspectJAutoProxyCreator 會(huì)在任何 Bean 創(chuàng)建之前嘗試返回 Bean 的實(shí)例。
【BeanPostProcessor 是在 Bean 對(duì)象創(chuàng)建完成初始化前后調(diào)用的】
【InstantiationAwareBeanPostProcessor 是在創(chuàng)建 Bean 實(shí)例之前嘗試用后置處理器返回對(duì)象的】
resolveBeforeInstantiation(beanName,mbdToUse)垦巴,解析 BeforeInstantiation媳搪。希望后置處理器在此能返回一個(gè)代理對(duì)象。如果能返回代理對(duì)象就使用骤宣,如果不能就繼續(xù)秦爆。
-
resolveBeforeInstantiation 方法里,后置處理器先嘗試返回對(duì)象憔披。
bean = applyBeanPostProcessorsBeforeInstantiation等限,拿到所有后置處理器爸吮,如果是 InstantiationAwareBeanPostProcessor,就執(zhí)行后置處理的 postProcessBeforeInstaniation 方法望门。
if(bean != null){
? bean = applyBeanPostProcessorsAfterInitialization
}
doCreateBean(beanName,mbdToUse,args)形娇,真正的去創(chuàng)建一個(gè) Bean 實(shí)例。
第一步
從 @EnableAspectJAutoProxy 開始分析筹误。首先關(guān)注 @Import桐早,將 AspectJAutoProxyRegistrar,給容器中導(dǎo)入 AspectJAutoProxyRegistrar厨剪。AspectJAutoProxyRegistrar 又實(shí)現(xiàn)了 ImportBeanDefinitionRegistrar 接口哄酝,這個(gè)接口可以自定義注冊(cè) Bean。
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy{}
AnnotationMetadata:當(dāng)前類的注解信息祷膳。
BeanDefinitionRegistry:BeanDefinition注冊(cè)類陶衅。
//ImportBeanDefinitionRegistrar
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry){
//根據(jù)class指定BeanDefintion信息
RootBeanDefinition beanDefinition = new RootBeanDefinition(A.class);
//注冊(cè)一個(gè) Bean,指定 bean 名稱
registry.registerBeanDefintion("rainBow",beanDefinition)
}
@EnableAspectJAutoProxy 利用 AspectJAutoProxyRegistrar 自定義給容器中注冊(cè) Bean直晨。那么它為 AOP 注冊(cè)了什么 Bean 那搀军?
可以在 AspectJAutoProxyRegistrar 的 registerBeanDefinitions 函數(shù)里尋找答案:
//AspectJAutoProxyRegistrar
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//想容器中注冊(cè)了一個(gè)名為 internalAutoProxyCreator,class 為 AnnotationAwareAspectJAutoProxyCreator 的 Bean勇皇。BeanDefinitionRegistry.registerBeanDefinition
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//拿到注解相關(guān)的信息
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
//根據(jù)拿到的注解的信息判斷 proxyTargetClass 和 exposeProxy 屬性
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
第一步總結(jié):利用 AspectJAutoProxyRegistrar 給容器中注冊(cè)了一個(gè) AnnotationAwareAspectJAutoProxyCreator 類型的 Bean罩句。
第二步
既然住了一個(gè) AnnotationAwareAspectJAutoProxyCreator,那么這個(gè)組件有什么作用那儒士?字面理解這個(gè) Bean 是注解模式切面自動(dòng)代理創(chuàng)建器的止。
先來看這個(gè)組件的繼承關(guān)系:
AnnotationAwareAspectJAutoProxyCreator
? ->AspectJAwareAdvisorAutoProxyCreator
? ->AbstractAdvisorAutoProxyCreator
? ->AbstractAutoProxyCreator
? implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
最源頭實(shí)現(xiàn)了一個(gè) Bean 后置處理器的接口和一個(gè) BeanFactory 的接口。后置處理器在 Bean 初始化完成前后做事情着撩,自動(dòng)裝配 BeanFactory 到實(shí)例中。首先看看這兩個(gè)接口對(duì)應(yīng)的 set 方法在哪里實(shí)現(xiàn)的匾委。
AbstractAutoProxyCreator.setBeanFactory()
AbstractAutoProxyCreator.后置處理器相關(guān)的邏輯
AspectJAwareAdvisorAutoProxyCreator.setBeanFactory()->initBeanFactory()
AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()拖叙,父類調(diào)用 setBeanFactory 的時(shí)候會(huì)調(diào)用 initBeanFactory 方法,這個(gè)方法又被子類重寫了赂乐,最后還會(huì)調(diào)用子類的 initBeanFactory 方法薯鳍。
AspectJAwareAdvisorAutoProxyCreator【InstantiationAwareBeanPostProcessor】的作用:
-
每個(gè) Bean 創(chuàng)建之前,調(diào)用 postProcessBeforeInstantiation 方法挨措。
關(guān)心我們加入切面的 Bean
- 判斷當(dāng)前 Bean 是否在 advisedBeans 中(保存了所有需要增強(qiáng)的 Bean)挖滤。
- 判斷當(dāng)前 Bean 是否是基礎(chǔ)類型,Advice浅役、Pointcut斩松、Advisor、AopInfrastructureBean觉既,或者是否是切面( @Aspect 注解)
- 判斷是否需要跳過惧盹,獲取候選的增強(qiáng)器(切面里的通知方法)乳幸,每一個(gè)封裝的通知方法的增強(qiáng)器是 InstantiationModelAwarePointcutAdvisor,判斷每一個(gè)增強(qiáng)器是否是 AspectJPointcutAdvisor 類型钧椰。
創(chuàng)建對(duì)象粹断。
-
Bean 創(chuàng)建之后,調(diào)用 postProcessAfterInitialization 方法嫡霞。
return wrapIfNecessary(bean, beanName,cacheKey); //包裝如果需要的情況下
獲取當(dāng)前 Bean 的所有增強(qiáng)器(通知方法)瓶埋。找到能在當(dāng)前 Bean 使用的增強(qiáng)器(哪些通知方法是要切入當(dāng)前 Bean 方法的)。然后給增強(qiáng)器排序诊沪。
保存當(dāng)前 Bean 到 advisedBean悬赏,表示當(dāng)前 Bean 已經(jīng)被增強(qiáng)了。
-
創(chuàng)建當(dāng)前 Bean 的代理對(duì)象娄徊,通過 proxyFactory 創(chuàng)建代理對(duì)象闽颇。需要傳入增強(qiáng)器。通過 proxyFactory 會(huì)創(chuàng)建兩種動(dòng)態(tài)代理寄锐。
JdkDynamicAopProxy(config); jdk 動(dòng)態(tài)代理兵多。實(shí)現(xiàn)了接口就用jdk。
ObjenesisCglibAopProxy(config); cglib 的動(dòng)態(tài)代理橄仆。
wrapIfNecessary 執(zhí)行結(jié)束剩膘,給容器中返回當(dāng)前組件使用 cglib 增強(qiáng)了的代理對(duì)象。以后容器中獲取到的就是這個(gè)組件的代理對(duì)象盆顾,執(zhí)行目標(biāo)方法的時(shí)候怠褐,代理對(duì)象就會(huì)執(zhí)行通知方法的流程。
-
目標(biāo)方法執(zhí)行您宪。
容器中保存了組件的代理對(duì)象(jdk 或 cglib 增強(qiáng)后的)奈懒,這個(gè)兌現(xiàn)管理保存了詳細(xì)信息,比如增強(qiáng)器宪巨,目標(biāo)對(duì)象磷杏。
CglibAopProxy.intercept() 方法,攔截目標(biāo)方法執(zhí)行捏卓。
-
根據(jù) ProxyFactory 獲取對(duì)象將要執(zhí)行的目標(biāo)方法連接器鏈 chain极祸。
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
List<Object> interceptorList 保存所有攔截器,一個(gè)默認(rèn)的 ExposeInvocationInterceptor 和 自定義的增強(qiáng)器
遍歷所有的增強(qiáng)器怠晴,將其轉(zhuǎn)為 Interceptor遥金,registry.getIntercepotr(advisor)
如果是 MethodInterceptor,直接加入集合蒜田,如果不是稿械,使用 AdvisorAdapter 將其增強(qiáng)轉(zhuǎn)為 MethodInterceptor。
-
如果沒有攔截器鏈物邑,直接執(zhí)行目標(biāo)方法溜哮。
攔截器鏈:每一個(gè)通知方法又被包裝為方法攔截器滔金,利用 MethodInterceptor 機(jī)制來執(zhí)行方法。
如果有攔截器鏈茂嗓,把需要執(zhí)行的目標(biāo)對(duì)象餐茵,目標(biāo)方法,連接器鏈等信息傳入創(chuàng)建一個(gè) CglibMethodInvocation 對(duì)象述吸,并調(diào)用 procceed 方法忿族,返回 retVal。
-
攔截器鏈的觸發(fā)過程
如果沒有攔截器執(zhí)行目標(biāo)方法蝌矛,最后一個(gè)攔截器也執(zhí)行目標(biāo)方法道批。
- 鏈?zhǔn)将@取每一個(gè)攔截器,攔截器執(zhí)行 invoke 方法入撒,每一個(gè)連接器等待下一個(gè)攔截器執(zhí)行完成返回以后再執(zhí)行隆豹,攔截器鏈的機(jī)制,保證通知方法與目標(biāo)方法的執(zhí)行順序茅逮。
總結(jié):
使用 @EnableAspectJAutoProxy 開啟 AOP 功能璃赡。
@EnableAspectJAutoProxy 會(huì)給容器中注冊(cè)一個(gè)組件 AnnotationAwareAspectJAutoProxyCreator。
AnnotationAwareAspectJAutoProxyCreator 是一個(gè)后置處理器献雅。
-
容器的創(chuàng)建過程:
registerBeanPostProcessors() 注冊(cè)后置處理器: 創(chuàng)建 AnnotationAwareAspectJAutoProxyCreator 對(duì)象碉考。
-
finishBeanFactoryInitialization() 初始化剩下的單實(shí)例 Bean。
創(chuàng)建業(yè)務(wù)邏輯組件和切面組件挺身。
AnnotationAwareAspectJAutoProxyCreator 會(huì)攔截組件的創(chuàng)建過程雨效。
-
組件創(chuàng)建完后蛤高,判斷組件是否需要增強(qiáng)
是:切面的通知方法撵彻,包裝成增強(qiáng)器(Advisor)艺演,給業(yè)務(wù)邏輯創(chuàng)建一個(gè)代理對(duì)象。
-
執(zhí)行目標(biāo)方法
代理對(duì)象執(zhí)行目標(biāo)方法
-
用 CglibAopProxy.intercept 進(jìn)行攔截伍玖。
得到目標(biāo)方法的攔截器鏈(增強(qiáng)器包裝成攔截器 MethodInterceptor)嫩痰。
利用攔截器的鏈?zhǔn)綑C(jī)制,依次進(jìn)入每一個(gè)攔截器進(jìn)行執(zhí)行窍箍。
-
效果:
前置通知->目標(biāo)方法->后置通知->返回通知/異常通知
Spring 事務(wù)
入口與 AOP 一樣,通過 @EnableTransactionManagement 來進(jìn)行源碼分析丽旅。
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement{
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
}
這個(gè)注解同樣有 @Import 注解椰棘,我們來關(guān)注 TransactionManagementConfigurationSelector 這個(gè)類來看到底為 Spring 事務(wù)導(dǎo)入了什么組件。
protected String[] selectImports(AdviceMode adviceMode) {
switch(adviceMode) {
case PROXY:
return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
default:
return null;
}
}
從上面這段代碼可以看出榄笙,這個(gè)注解為我們導(dǎo)入兩個(gè)組件邪狞,AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration。
我們依次來看這兩個(gè)組件就能明白 Spring 事務(wù)到底是怎么實(shí)現(xiàn)的了茅撞。
AutoProxyRegistrar
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
public AutoProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Object proxyTargetClass = candidate.get("proxyTargetClass");
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
if (mode == AdviceMode.PROXY) {
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean)proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
}
從代碼來看帆卓,他實(shí)現(xiàn)了 ImportBeanDefinitionRegistrar 接口巨朦,功能就不用解釋了,調(diào)用 registerBeanDefinitions 方法給容器中注冊(cè) Bean 的剑令。
因?yàn)?EnableTransactionManagement 里定義的 mode 就是 AdviceMode.PROXY糊啡,而且 proxyTargetClass 是false,所以會(huì)執(zhí)行如下代碼:
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
給容器中注冊(cè)一個(gè) InfrastructureAdvisorAutoProxyCreator 組件吁津,這個(gè)組件也是一個(gè)后置處理器棚蓄。
作用:利用后置處理器機(jī)制,在對(duì)象創(chuàng)建以后碍脏,包裝對(duì)象梭依,返回一個(gè)代理對(duì)象(增強(qiáng)器),代理對(duì)象執(zhí)行方法典尾,利用連接器鏈進(jìn)行調(diào)用役拴。
ProxyTransactionManagementConfiguration
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
public ProxyTransactionManagementConfiguration() {
}
@Bean(
name = {"org.springframework.transaction.config.internalTransactionAdvisor"}
)
@Role(2)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(this.transactionAttributeSource());
advisor.setAdvice(this.transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder((Integer)this.enableTx.getNumber("order"));
}
return advisor;
}
@Bean
@Role(2)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(2)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(this.transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
首先 ProxyTransactionManagementConfiguration 也是一個(gè)配置類,利用 @Bean 給容器中注冊(cè)了一些組件钾埂。
首先注冊(cè)了一個(gè) BeanFactoryTransactionAttributeSourceAdvisor 事務(wù)增強(qiáng)器河闰。事務(wù)增強(qiáng)器需要注解里面信息。
我們關(guān)注代碼中注冊(cè)時(shí)需要傳入一個(gè)事務(wù)屬性勃教,這個(gè)屬性在下面也是注入的一個(gè) Bean淤击。
advisor.setTransactionAttributeSource(this.transactionAttributeSource());
@Bean
@Role(2)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
AnnotationTransactionAttributeSource 注冊(cè)了好多的注解解析器來支持各種類型的注解,包擴(kuò) Spring 注解故源,Jta 注解污抬,Ejb3 注解等等。
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = new LinkedHashSet(2);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
接下來看事務(wù)增強(qiáng)器的第二個(gè)屬性绳军,事務(wù)攔截器印机,這個(gè)屬性也是下面注冊(cè)的一個(gè) Bean。
advisor.setAdvice(this.transactionInterceptor());
@Bean
@Role(2)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(this.transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
擴(kuò)展組件
BeanFactoryPostProcessor
我們以前了解過 BeanPostProcessor门驾,它們之間有什么區(qū)別那射赛?
BeanPostProcessor:bean 后置處理器,bean 創(chuàng)建對(duì)象初始化前后進(jìn)行攔截工作的奶是。
BeanFactoryPostProcessor:beanFactory 的后置處理器楣责,在 BeanFactory 標(biāo)準(zhǔn)初始化之后調(diào)用,所有的 BeanDefifnition 都已經(jīng)保存加載到 beanFactory 中聂沙,但是 bean 的實(shí)例還未創(chuàng)建秆麸。
IOC 容器創(chuàng)建對(duì)象
invokeBeanFactoryPostProcessors(beanFactory)。
如何找到所有的 BeanFactoryPostProceessor 并執(zhí)行它們的方法:
- 直接在 BeanFactory 中找到所有類型是 BeanFactoryPostProcessor 的組件及汉,并執(zhí)行它們的方法沮趣。
- 在初始化創(chuàng)建其他組件前面執(zhí)行。
BeanDefinitionRegistryPostProcessor
可以將 BeanDefinitionRegistry 理解為 BeanDefinition 的保存中心坷随,以后 BeanFactory 按照 BeanDefinitionRegistry 里面保存的每一個(gè) bean 定義信息創(chuàng)建 bean 的實(shí)例房铭。
下面我們來看 BeanFactoryPostProcessor 的子接口:
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
額外定義了一個(gè) postProcessBeanDefinitionRegistry 方法驻龟,在所有 bean 的定義信息將要被加載,bean 實(shí)例還未被創(chuàng)建時(shí)執(zhí)行缸匪,在 BeanFactoryPostProceessor 之前執(zhí)行翁狐,因?yàn)?BeanFactoryPostProceessor 是在 bean 的定義信息已經(jīng)被加載后執(zhí)行。
可以利用 BeanDefinitionRegistryPostProcessor 給容器中額外添加一些組件豪嗽。
原理:
- IOC 創(chuàng)建對(duì)象
- refresh()->invokeBeanFactoryPostProcessors(beanFactory)谴蔑;
- 先從容器中獲取到所有的 BeanDefinitionRegistryPostProcessors 組件,依次觸發(fā)所有的 postProcessBeanDefinitionRegistry() 方法龟梦,再觸發(fā) BeanFactoryPostProcessor隐锭。
- 再來從容器中找到 BeanFactoryPostProcessor 組件,一次觸發(fā) postProcessBeanFactory() 方法计贰。
ApplicationListener
監(jiān)聽容器中發(fā)布的事件钦睡,完成事件驅(qū)動(dòng)模型的開發(fā)。
public interface ApplicationListener<E extends ApplicationEvent>
監(jiān)聽 ApplicationEvent 及其子類躁倒。
基于事件開發(fā)的步驟:
寫一個(gè)監(jiān)聽器來監(jiān)聽某個(gè)事件荞怒,ApplicationEvent 及其子類。
-
或者使用 @EventListener 注解讓任意組件都能監(jiān)聽事件秧秉,使用 EventListenerMethodProcessor 這個(gè)處理器來解析這個(gè)注解褐桌。
- 實(shí)現(xiàn)了 SmartInitializingSingleton。
把監(jiān)聽器加入到容器象迎。
-
只要容器中有相關(guān)事件的發(fā)布荧嵌,我們就能監(jiān)聽到這個(gè)事件。
ContextRefreshedEvent:容器刷新完成(所有 Bean 都創(chuàng)建完成)會(huì)發(fā)布這個(gè)事件砾淌。
ContextCloseEvent:關(guān)閉容器會(huì)發(fā)布這個(gè)事件啦撮。
發(fā)布一個(gè)事件:applicationContext.pushlishEvent。
原理:
ContextRefreshEvent 事件
容器創(chuàng)建對(duì)象:refresh()
finishRefresh()汪厨,容器刷新完成
-
publishEvent(new ContextRefreshedEvent(this))
【發(fā)布流程】
獲取事件多播器(派發(fā)器):getApplicaitonEvnetMulticaster()
multicastEvent 派發(fā)事件
-
獲取到所有的 ApplicationListener
如果 Listener 里有 Executor赃春,可以支持使用 Executor 進(jìn)行異步派發(fā)。
Executor executor = getTaskExecutor();
否則同步的方式直接執(zhí)行 listener 方法劫乱,里面通過 listener 回調(diào) onApplicationEvent(envet) 方法织中。
invokeListener(listener, event);
SmartInitializingSingleton
所有單實(shí)例 Bean 創(chuàng)建完成之后觸發(fā)。
// 所有的單實(shí)例 Bean 創(chuàng)建完后執(zhí)行
public interface SmartInitializingSingleton{
void afterSingletonsInstantiated();
}
過程:
- IOC 容器創(chuàng)建對(duì)象并 refresh 容器
- finishBeanFactoryInitialization(beanFactory)衷戈,初始化剩下的單實(shí)例 Bean抠璃。
- 創(chuàng)建所有的單實(shí)例 Bean,for 循環(huán) + getBean() .
- 獲取創(chuàng)建好的單實(shí)例 Bean脱惰,判斷是否是 SmartInitializingSingleton,如果是就調(diào)用 afterSingletonsInstantiated 方法窿春。