Spring 源碼的核心組件:javascript
IOC 容器能夠理解爲一個 Map,key 就是咱們日常使用 Spring 框架時寫的 Bean Id,value 就是對應類的實例化對象。java
在開始分析源碼以前,咱們先試着瞭解幾個概念,這幾個類對於咱們理解源碼有着很大的幫助,方便對整個 Spring 源碼進行分析。spring
ApplicationContext,BeanFactory
提到 Spring 就一直說容器,這個容器咱們上面也給出了一個直觀的解釋,能夠理解爲一個 Map,用來存儲實例化的的對象,須要的時候就從容器裏面取就能夠了。那麼在代碼中的具體實現是什麼那?編程
你們最爲熟悉的實現可能就是 ApplicationContext,它就是一個容器,而它實現了 BeanFactory 接口,能夠說 BeanFactory 就是最基礎的容器,ApplicationContext 至關於在 BeanFactory 接口增長了一些功能,它們均可以稱爲容器。緩存
先來看看 BeanFactory 的代碼:markdown
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); }
整個接口定義的抽象方法其實很是簡單和直接,主要就是各類個樣的 getBean 方法和一些判斷是不是單例或者原型的方法。app
再來看 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; }
不只僅實現了 BeanFactory 接口,並且實現了事件派發器,資源解析器以及環境參數相關的接口,比 BeanFactory 多了許多功能。異步
下面來看看經常使用的容器,也就是上面接口的實現類。async
BeanDefinition
BeanDefinition 按照字面意思理解就是 Bean 的定義信息,咱們從接口的定義來看看這個類到底保存了什麼信息。
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 類名稱,做用域【單例或者原型】,構造函數的參數,屬性等等,這些信息也說明這個類是 Spring 用來構建 Bean 的主要的類。
這個接口的主要實現類有 RootBeanDefinition,ChildBeanDefinition,GenericBeanDefinition等等。其中 RootBeanDefinition 最爲經常使用,至關於 xml 文件中的
BeanDefinitionRegistry
既然有了材料 BeanDefinition,下面必定須要一個操做它的類,BeanDefinitionRegistry 就是一個用來幫咱們操做 BeanDefinition 的接口,它的裏面有許多操做 BeanDefinition 的方法,包括經過 BeanDefinition 註冊 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 方法將一個 Bean 註冊到容器中。調用 BeanDefinitionRegistry.registerBeanDefinition 手工進行註冊。
java BeanDefinitionRegistry registry = context.getRegistry(); boolean definition = registry.containsBeanDefinition("person");
BeanPostProcessor
BeanPostProcessor,bean 的後置處理器,在 bean 初始化先後進行一些處理工做。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; } }
由此衍生出來的後置處理器很是多,處理時機也不同,咱們會在後面的源碼分析對這些後置處理器的實現原理和操做時機進行一個總結。
Spring 底層對 BeanPostProcessor 的使用:bean 賦值,注入其餘組件,@Autowired,聲明週期註解功能,@Async等等。
ApplicationContextAware
自定義組件想要使用 Spring 容器底層的一些組件(ApplicationContext,BeanFactory,xxx)等等,須要自定義組件實現 xxxAware 接口。在建立對象的時候,會調用接口規定的方法注入相關組件。ApplicationContextAware 會將 IOC 容器傳入到組件中,BeanNameAware 會講當前實例在 IOC 容器中 Bean 的名字傳入到實例中。這些 Aware 會有對應的 AwareProcessor 來進行邏輯處理。
public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext var1) throws BeansException; }
若是想往組件中注入容器能夠實現 ApplicationContextAware 接口,而後經過 setApplicationContext 保存起來。 咱們對 Spring 功能進行擴展時經常喲昂到這些 Aware。
ApplicationListener 與 ApplicationEventMulticaster
這兩個組件是 Spring 事件驅動模型用到的組件,ApplicationListener:事件監聽。ApplicationEventMulticaster:事件派發。
Bean 的聲明週期指的是 Bean 的建立-->初始化-->銷燬的過程,Spring 把這個過程所有交給容器來管理。咱們能夠自定義初始化和銷燬方法,容器在 Bean 進行到當前生命週期的時候來調用咱們自定一的初始化和銷燬方法。
構造(對象建立)
單實例:在容器啓動的時候建立對象。
多實例:在每次獲取的時候建立對象,調用 getBean 方法時。
初始化
對象建立完成,並賦值好,調用初始化方法
銷燬
單實例:容器關閉的時候。
多實例:容器會建立 Bean, 但不會管理 Bean,容器不會調用銷燬方法。
Bean 的生命週期要比上面寫的更加複雜,咱們在分析完源碼後會對這部分進行一個總結。
@Import,快速給容器中導入一個組件,@Import(Color.class) 至關於一個無參構造函數。id 默認是全類名。
@Conditional 知足必定條件纔給容器中註冊bean,這個能夠用來讓兩個bean造成依賴,能夠用在方法上,也能夠用在類上。這個註解在 SpringBoot 用的很是多。
最後說說 @Autowired 和 @Resource 的區別:
@Autowired 自動注入默認按照 type 注入,即按照 .class 查找。若是找到多個相同類型的組件,在將屬性的名稱做爲組件的 id 去容器中查找。使用 @Qualifier("bookDao") 與 @Autowired 組合能夠明確指定須要裝配的 Bean,經過 id。
@Autowired(require=false) 有就裝配,沒有就變爲 null。
Spring 還支持 JSR250 和 JSR330 裏的 @Resource 和 @Inject 註解。Java 規範的註解。@Resource 和 @Autowired 同樣實現自動裝配,默認按照屬性名稱進行自動裝配。不支持 @Primary,也不支持 @Autowired(require=false)。
@Inject 須要額外導入包,功能和 @Autowired 同樣,不支持 require=false;
@Autowired 能夠標註在構造器、參數、方法、屬性上。
有了一些概念後,咱們內心必定會有一些問題,同時帶着問題去看源碼也有助於咱們更加快速地切入到 Spring 得核心,不墨跡,直給。
下面咱們帶着問題去看看源碼。
仍是從下面這段代碼開始
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
new 容器的過程到底執行了什麼操做那?前兩步是預處理和配置類的解析工做,咱們直接看 refresh 方法,這個方法就是容器的建立和刷新以及 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(); } } }
refreshBeanFactory(),刷新【建立】 BeanFactory。
在 GenericApplicationContext 裏無參構造器建立一個 BeanFactory 對象。
this.beanFactory = new DefaultListableBeanFactory();
設置一個 Id。
getBeanFactory(),返回剛纔 GenericApplicationContext 建立的 BeanFactory 對象。剛建立,裏面都是默認的配置。
將建立的 BeanFactory【DefaultListableBeanFactory】返回。
設置 BeanFactory 的類加載器、支持表達式解析器。。。
添加 部分的BeanPostProcessor【ApplicationContextAwareProcessor】
設置忽略自動裝配的接口,EnvironmentAware、EmbeddedValueResolverAware。。。
註冊能夠解析的自動裝配,咱們能夠在任何組件中自動注入,ResourceLoader,BeanFactory,ApplicationContext。
添加 BeanPostProcessor【ApplicationListenerDetector】。
添加編譯時的 AspectJ。
給 BeanFactory 中註冊一些能用的組件。
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()); } }
=============================以上是 BeanFactory 建立及準備================================
BeanFactoryProcessor:BeanFactory 的後置處理器,在 BeanFactory 標準初始化執行的 Processor,標準初始化就是以上四部。
兩個主要接口,BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor(能夠用這個來註冊一些新的組件 )。
執行 BeanPostProcessor 的方法:
先執行 BeanDefintionRegistryPostProcessor
獲取全部的 BeanDefinitionRegistryPostProcessor。
對於實現了 PriorityOrdered 優先級接口的 BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
對於實現了 Ordered 順序接口的 BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
最後執行沒有實現任何優先級或者是順序接口的 BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
在執行 BeanFactoryPostProcessor 的方法
不一樣接口類型的 BeanPostProcessor,在 Bean 建立先後的執行時機是不同的。
BeanPostProcessor
DestructionAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor【internalPostProcessors】
獲取全部的 BeanPostProcessor,後置處理器都默承認以有 PriorityOrdered,Ordered 來指定優先級。
先註冊 PriorityOrdered 優先級接口的 BeanPostProcessor,把每個 BeanPostProcessor 添加到 BeanFactory 中。
beanFactory.addBeanPostProcessor(postProcessor)
再註冊 Ordered 接口的。
最後註冊沒有實現任何優先級接口的。
最終註冊,MergedBeanDefinitionPostProcessor。
註冊一個 ApplicationListenerDetector,來在 Bean 建立完成後檢查是不是 ApplicationListener,若是是
applicationContext.addApplicationListener((ApplicationListener<?>) bean);
獲取 BeanFactory。
判斷容器有沒有 id 爲 messageSource 的,類型是 MessageSource 的組件
若是有賦值給 messageSource 屬性,若是沒有本身建立一個 DelegatingMessageSource。
MessageSource 取出國際化配置文件中的某個 key 值,能按照區域信息獲取。
把建立好的 MessageSource 註冊到容器中,之後獲取國際化配置文件的值的時候,能夠自動注入 MessageSource,調用 getMessage 方法就能夠獲取到了。
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)
onRefresh,留給子容器(子類),重寫 onRefresh 方法,在容器刷新時能夠再自定義邏輯。
registerListeners,給容器中把項目裏的 ApplicationListener 註冊進來。
從容器中拿到全部的 ApplicationListener 組件,將每一個監聽器添加到事件派發器中。
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)
派發以前步驟產生的事件,派發器沒初始化以前的。
//初始化全部剩下的單實例 bean。 beanFactory.preInstantiateSingletons();
獲取容器中的全部 BeanDefinitions,依次進行初始化和建立對象。
若是 Bean 不是抽象的,是單實例,不是懶加載的,就開始建立單例 Bean。
判斷是不是 FactoryBean,便是否實現了 FactoryBean 接口的 Bean,若是是就用工廠方法建立對象。
若是不是工廠 Bean,利用 getBean(beanName) 建立對象。
getBean(beanName),就是本身寫測試類的那個 getBean。
調用 doGetBean(name,null,null,false)。
先獲取緩存中保存的單實例 Bean,若是能獲取到說明這個 Bean 以前被建立過了(全部建立過的單實例 Bean 都會被緩存起來)。
//保存單實例 Bean 的 private final Map<String,Object> singletonObjects = new ConcurrentHashMap<String,Object>(256);
緩存中獲取不到,開始 Bean 的建立對象流程。
標記當前 Bean 已經被建立。
獲取 Bean 的定義信息。
獲取當前 Bean 所依賴的其餘 Bean,若是有就按照 getBean() 把依賴的 Bean 先建立出來。
啓動單實例 Bean 的建立流程。
createBean(beanName,mbd,args); //讓 BeanPostProcessor 攔截返回對象。正常的 BeanPostProcessor 是對象建立完成初始化以前執行的,而這個 BeanPostProcessor 要在 Bean 建立以前執行 //InstantiationAwareBeanPostProcessor 提早執行 //觸發 postProcessBeforeInstantiation 方法 //若是上一步有返回值,在觸發 postProcessAfterInitialization 方法 Object bean = resolveBeforeInstantiation(beanName,mbdToUse);
若是 InstantiationAwareBeanPostProcessor 沒有返回代理對象,調用下面的方法建立 Bean。
Object beanInstance = doCreateBean(beanName,mbcToUse,args); //建立 Bean 實例,利用工廠方法或者對象的構造器建立出 Bean 實例。 createBeanInstance(beanName,mbd,args); // 建立實例對象後,執行後置處理器 // 利用 MergedBeanDefintionPostProcessor applyMergedBeanDefintionPostProcessor(mbd,beanType,beanName); bdp.postProcessMergedBeanDefinition(mbd,beanType,beanName);
對 Bean 的屬性進行賦值
populateBean(beanName,mbd,instanceWrapper); //賦值以前拿到 InstantiationAwareBeanPostProcessor 後置處理器 //執行 postProcessAfterInstantiation //再拿 InstantiationAwareBeanPostProcessor 後置處理器 //執行 postProcessPropertyValues 方法 //最後一步,應用 Bean 屬性的值,利用 setter 方法等用反射賦值。 applyPropertyValues(beanName,mbd,bw,pvs);
對 Bean 進行初始化
initializeBean(beanName,exposedObject,mbd); //執行 Aware 接口的方法 //判斷是不是 BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,利用 invoke 回調接口的方法。 invokeAwareMethods(beanName,bean); //執行全部後置處理器初始化以前的方法 applyBeanPostProcessorsBeforeInitialization(wrapperBean) //執行後置處理器的回調方法 BeanPostProcessor.postProcessBeforeInitialization() //執行初始化方法 invokeInitMethods(beanName,wrappedBean,mbd); //是不是 InitializingBean 接口實現類,執行接口規定的初始化。 //是否自定義初始化方法。 //執行初始化以後後置處理器的方法 applyBeanPostProcessorsAfterInitialization(wrapperBean) //執行後置處理器的回調方法 BeanPostProcessor.postProcessAfterInitialization()
註冊 Bean 的銷燬方法。不執行方法,在容器銷燬時執行。
·將建立的 Bean 添加到緩存 singletonObjects 中。IOC 容器就能夠理解爲這些 Map,這些 Map 裏面保存了不少單實例 Bean,環境信息。
檢查全部 Bean 是否實現了 SmartInitializingSingleton 接口,若是是,就執行回調方法。
初始化和聲明週期有關的後置處理器
initLifecycleProcessor(); //先從容器中找,找不到 new 一個 Default 的,而且註冊在 BeanFactory 中,能夠注入到組件中。 //容許寫 LifecycleProcessor, 能夠在 BeanFactory 刷新完成或者關閉時調用一些方法。 void onRefresh(); void onClose();
拿到前面定義的生命週期處理器,回調 onRefresh 方法。
發佈容器刷新完成事件。
publishEvent(new ContextRefreshedEvent(this));
總結:
Spring 建立 Bean 的時機:
後置處理器:
每個 Bean 建立完成後,都會使用各類後置處理器進行處理,來加強 Bean 的功能。
總體啓動流程:
傳入配置類,建立 IOC 容器。
註冊配置類,調用 refresh() 刷新容器。
registerBeanPostProcessors(beanFacotry),註冊 Bean 的後置處理器方便攔截 Bean 的建立。
獲取 IOC 容器中已經定義了的須要建立對象的全部 BeanPostProcessor,配置類裏註冊的。
給容器中加其餘的 PostProcessor。
優先註冊了實現了 PriorityOrdered 接口的 BeanPostProcessor。
再給容器中註冊實現了 Ordered 接口的 BeanPostProcessor。
最後註冊沒實現優先級接口的 BeanPostProcessor。
註冊 BeanPostProcessor,實際上就是建立 BeanPostProcessor 的對象並保存在容器中。
建立 internalAutoProxyCreator 的 BeanPostProcessor[AnnotationAwareAspectJAutoProxyCreator]
把 BeanPostProcessor 註冊到 BeanFactory 中:
beanFactory.addBeanPostProcessor(postProcessor)。
==========以上是建立和註冊 AnnotationAwareAspectJAutoProxyCreator 的過程=========
AnnotationAwareAspectJAutoProxyCreator 這個 BeanPostProcessor 作了什麼?
看給容器中註冊了什麼組件,這個組件何時工做,有什麼功能?
AnnotationAwareAspectJAutoProxyCreator => InstantiationAwareBeanPostProcessor
finishBeanFactoryInitialization(beanFactoty),完成 BeanFactory 的初始化工做,建立剩下的單實例 Bean。
getBean->doGetBean()->getSingleton()
建立 Bean
【AnnotationAwareAspectJAutoProxyCreator 在全部 Bean 建立以前會有一個攔截,由於實現了InstantiationAwareBeanPostProcessor,會調用 postProcessBeforeInstantiation 方法】
先從緩存中獲取當前 Bean,若是能獲取到,說明 Bean 是以前被建立過的,直接使用,不然再建立。只要建立好的 Bean 都會被緩存起來。
createBean(),建立 Bean。AnnotationAwareAspectJAutoProxyCreator 會在任何 Bean 建立以前嘗試返回 Bean 的實例。
【BeanPostProcessor 是在 Bean 對象建立完成初始化先後調用的】
【InstantiationAwareBeanPostProcessor 是在建立 Bean 實例以前嘗試用後置處理器返回對象的】
resolveBeforeInstantiation(beanName,mbdToUse),解析 BeforeInstantiation。但願後置處理器在此能返回一個代理對象。若是能返回代理對象就使用,若是不能就繼續。
resolveBeforeInstantiation 方法裏,後置處理器先嚐試返回對象。
bean = applyBeanPostProcessorsBeforeInstantiation,拿到全部後置處理器,若是是 InstantiationAwareBeanPostProcessor,就執行後置處理的 postProcessBeforeInstaniation 方法。
if(bean != null){
bean = applyBeanPostProcessorsAfterInitialization
}
doCreateBean(beanName,mbdToUse,args),真正的去建立一個 Bean 實例。
從 @EnableAspectJAutoProxy 開始分析。首先關注 @Import,將 AspectJAutoProxyRegistrar,給容器中導入 AspectJAutoProxyRegistrar。AspectJAutoProxyRegistrar 又實現了 ImportBeanDefinitionRegistrar 接口,這個接口能夠自定義註冊 Bean。
@Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy{}
AnnotationMetadata:當前類的註解信息。
BeanDefinitionRegistry:BeanDefinition註冊類。
//ImportBeanDefinitionRegistrar @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry){ //根據class指定BeanDefintion信息 RootBeanDefinition beanDefinition = new RootBeanDefinition(A.class); //註冊一個 Bean,指定 bean 名稱 registry.registerBeanDefintion("rainBow",beanDefinition) }
@EnableAspectJAutoProxy 利用 AspectJAutoProxyRegistrar 自定義給容器中註冊 Bean。那麼它爲 AOP 註冊了什麼 Bean 那?
能夠在 AspectJAutoProxyRegistrar 的 registerBeanDefinitions 函數裏尋找答案:
//AspectJAutoProxyRegistrar public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //想容器中註冊了一個名爲 internalAutoProxyCreator,class 爲 AnnotationAwareAspectJAutoProxyCreator 的 Bean。BeanDefinitionRegistry.registerBeanDefinition AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //拿到註解相關的信息 AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); //根據拿到的註解的信息判斷 proxyTargetClass 和 exposeProxy 屬性 if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } }
第一步總結:利用 AspectJAutoProxyRegistrar 給容器中註冊了一個 AnnotationAwareAspectJAutoProxyCreator 類型的 Bean。
既然住了一個 AnnotationAwareAspectJAutoProxyCreator,那麼這個組件有什麼做用那?字面理解這個 Bean 是註解模式切面自動代理建立器。
先來看這個組件的繼承關係:
AnnotationAwareAspectJAutoProxyCreator
->AspectJAwareAdvisorAutoProxyCreator
->AbstractAdvisorAutoProxyCreator
->AbstractAutoProxyCreator
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
最源頭實現了一個 Bean 後置處理器的接口和一個 BeanFactory 的接口。後置處理器在 Bean 初始化完成先後作事情,自動裝配 BeanFactory 到實例中。首先看看這兩個接口對應的 set 方法在哪裏實現的。
AbstractAutoProxyCreator.setBeanFactory()
AbstractAutoProxyCreator.後置處理器相關的邏輯
AspectJAwareAdvisorAutoProxyCreator.setBeanFactory()->initBeanFactory()
AnnotationAwareAspectJAutoProxyCreator.initBeanFactory(),父類調用 setBeanFactory 的時候會調用 initBeanFactory 方法,這個方法又被子類重寫了,最後還會調用子類的 initBeanFactory 方法。
AspectJAwareAdvisorAutoProxyCreator【InstantiationAwareBeanPostProcessor】的做用:
每一個 Bean 建立以前,調用 postProcessBeforeInstantiation 方法。
關心咱們加入切面的 Bean
建立對象。
Bean 建立以後,調用 postProcessAfterInitialization 方法。
return wrapIfNecessary(bean, beanName,cacheKey); //包裝若是須要的狀況下
獲取當前 Bean 的全部加強器(通知方法)。找到能在當前 Bean 使用的加強器(哪些通知方法是要切入當前 Bean 方法的)。而後給加強器排序。
保存當前 Bean 到 advisedBean,表示當前 Bean 已經被加強了。
建立當前 Bean 的代理對象,經過 proxyFactory 建立代理對象。須要傳入加強器。經過 proxyFactory 會建立兩種動態代理。
JdkDynamicAopProxy(config); jdk 動態代理。實現了接口就用jdk。
ObjenesisCglibAopProxy(config); cglib 的動態代理。
wrapIfNecessary 執行結束,給容器中返回當前組件使用 cglib 加強了的代理對象。之後容器中獲取到的就是這個組件的代理對象,執行目標方法的時候,代理對象就會執行通知方法的流程。
目標方法執行。
容器中保存了組件的代理對象(jdk 或 cglib 加強後的),這個兌現管理保存了詳細信息,好比加強器,目標對象。
CglibAopProxy.intercept() 方法,攔截目標方法執行。
根據 ProxyFactory 獲取對象將要執行的目標方法鏈接器鏈 chain。
List