本篇文章篇幅較大,但願讀者能夠慢慢閱讀,建議收藏,分屢次閱讀學習。java
學習源碼的過程中,有幾點建議:spring
必定要學會抓重點,概括核心類、核心方法、核心步驟;設計模式
分析源碼咱們不須要太過於糾結細節,否則,這個源碼最起碼得分析月才能分析完;緩存
主要的目的是分析整個容器初始化過程,怎麼初始化bean,怎麼設置動態代理;咱們主要學習的是他們的思想,以及代碼中運用到的設計模式;app
BeanFactory:用於訪問容器中bean的接口,使用的是工廠模式,重點注意DefaultListableBeanFactory,是貫穿的整個容器的基本工廠類。框架
BeanDefinition:BeanDefinition是bean在Spring中的描述,先讀取到bean的各類元素,而後利用BeanDefinition去初始化bean,是spring從起管理bean對象的數據模型。編輯器
BeanDefinitionRegistry接口:註冊bean定義到Spring容器中,與BeanFactory接口相對應,主要針對於Bean的註冊,BeanFactory主要針對於bean對象的管理。ide
BeanFactoryPostProcessor接口:bean工廠後置處理器,該接口的做用主要是提供擴展點,用於各類bean定義的註冊和實例化等,比較須要主要關注ConfigurationClassPostProcessor該類;函數
BeanPostProcessor接口:bean的後置處理器,該接口提供的擴展點,用於初始化bean,以及初始化完成後的各類擴展;源碼分析
首先讀取BeanDefinition放到容器中。
經過BeanFactoryPostProcessor對象的擴展
經過BeanPostProcessor對象的擴展
而後根據BeanDefinition去初始化bean。
最後實際進行初始化而後保存到容器中。
來實現各類不一樣的功能;IOC容器初始化大體的一個流程,主要是看AnnotationConfigApplicationContext和refresh
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { //初始化容器,建立bean工廠,加載各類內部重要類的bean定義,用於初始化咱們或者其餘引入類 this(); //註冊咱們配置類的bean定義,初始化容器,從這個類開始 register(componentClasses); //準備工做作好後,開始初始化容器 refresh(); }
AnnotatedBeanDefinitionReader:主要用於讀取相關內部的Spring容器的Bean對象。
public AnnotationConfigApplicationContext() { //初始化讀取bean定義的讀取器,完成Spring內部bean定義的註冊 this.reader = new AnnotatedBeanDefinitionReader(this); //初始化一個類掃描器,其實這個方法進來,是沒有用到這個掃描器的 this.scanner = new ClassPathBeanDefinitionScanner(this); }
從上面建立bean定義讀取器,看下構造方法
//從上面建立bean定義讀取器,看下構造方法 public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); } public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); //把ApplicationContext對象賦值給bean定義讀取器 this.registry = registry; this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); //主要是看這個方法,註冊Spring內部重要的bean定義 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
到這裏this(),這個方法流程就過完了,主要就是註冊spring內部重要的bean定義,來看下register(componentClasses)方法
//此目的主要針對於上面註冊的reader進行註冊相關的bean public void register(Class<?>... annotatedClasses) { Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified"); //使用上面初始化的bean定義讀取器,去註冊咱們配置類的bean定義 this.reader.register(annotatedClasses); } //遍歷去註冊傳入進來的註解相關的Bean對象 public void register(Class<?>... annotatedClasses) { for (Class<?> annotatedClass : annotatedClasses) { registerBean(annotatedClass); } } // public void registerBean(Class<?> annotatedClass) { doRegisterBean(annotatedClass, null, null, null); } //註冊bean定義 private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) { //根據配置類建立一個bean定義 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } abd.setInstanceSupplier(supplier); //解析bean的做用域,若是沒有設置,則默認是單例 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); // 建立bean對象的bean名稱 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); //解析該bean是否有Lazy,Primary,DependsOn,Description等註解,有則填充進去 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); if (qualifiers != null) { for (Class<? extends Annotation> qualifier : qualifiers) { //判斷是不是Primary if (Primary.class == qualifier) { abd.setPrimary(true); } // 判斷是否屬於懶惰加載 else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } if (customizers != null) { for (BeanDefinitionCustomizer customizer : customizers) { customizer.customize(abd); } } // 構建BeanDefinitionHolder對象去引用對象 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); //最後把該bean定義註冊到Bean工廠中去 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
register(componentClasses),方法到此結束,而後咱們分析refresh();方法,該方法初始化了IOC容器。
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //設置容器狀態,準備刷新容器 prepareRefresh(); //獲取到容器的bean工廠 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //填充bean工廠的各類屬性 prepareBeanFactory(beanFactory); try { //留給子類實現,咱們看的AnnotationConfigApplicationContext繼承了GenericApplicationContext,該類主要是註冊了ServletContextAwareProcessor postProcessBeanFactory(beanFactory); //主要調用bean工廠的後置處理器,把咱們的類,註冊成bean定義 invokeBeanFactoryPostProcessors(beanFactory); // 註冊 BeanPostProcessor 的實現類 // 此接口兩個方法: postProcessBeforeInitialization 和 postProcessAfterInitialization // 兩個方法分別在 Bean 初始化以前和初始化以後獲得執行。注意,到這裏 Bean 還沒初始化 registerBeanPostProcessors(beanFactory); //初始化國際化資源(這個方法不重要) initMessageSource(); //Spring事件相關,主要是建立一個事件多播器 initApplicationEventMulticaster(); //留給子類實現 onRefresh(); //把咱們的事件註冊到容器中 registerListeners(); //實例化咱們須要的bean,放入IOC容器 finishBeanFactoryInitialization(beanFactory); //完成容器IOC容器初始化,而且發佈初始化完成事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } destroyBeans(); cancelRefresh(ex); throw ex; } finally { resetCommonCaches(); } } }
protected void prepareRefresh() { // 記錄啓動時間, // 將 active 屬性設置爲 true,closed 屬性設置爲 false,它們都是 AtomicBoolean 類型 this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // Initialize any placeholder property sources in the context environment initPropertySources(); // 校驗 xml 配置文件 getEnvironment().validateRequiredProperties(); this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); }
obtainFreshBeanFactory() 建立 Bean 容器,加載並註冊 Bean IoC初始化裏面最重要的部分。
關鍵是如下幾步:
注意:這步完成後,Bean 並無完成初始化,實際的實例並無被建立。
AbstractApplicationContext#obtainFreshBeanFactory()
protected ConfigurableListableBeanFactory obtainFreshBeanFactory(){ // 關閉舊的 BeanFactory (若是有),建立新的 BeanFactory,加載 Bean 定義、註冊 Bean 等等 refreshBeanFactory(); // 返回上一步剛剛建立的BeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
AbstractRefreshableApplicationContext#refreshBeanFactory()
protected final void refreshBeanFactory() throws BeansException { // 若是 ApplicationContext 已經加載過 BeanFactory,銷燬全部的Bean,關閉BeanFactory // 注意點:應用中BeanFactory是能夠有多個的,這裏可不是說全局是否有BeanFactory // 而是說當前的ApplicationContext有沒有BeanFactory! if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { // 初始化一個 DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); // 用於 BeanFactory 的序列化,通常人應該用不到吧... beanFactory.setSerializationId(getId()); // 下面是兩個重點方法 // 設置 BeanFactory 的兩個重要屬性 // 是否容許 Bean 覆蓋、是否容許循環引用 customizeBeanFactory(beanFactory); // 加載BeanDefinition到BeanFactory 單獨拉出來說 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
能夠感受到一個設計思路,ApplicationContext 繼承自 BeanFactory,可是它不該該被理解爲 BeanFactory 的實現類,而是說其內部持有一個實例化的 BeanFactory(DefaultListableBeanFactory)。之後全部的 BeanFactory 相關的操做實際上是委託給這個實例來處理的。
customizeBeanFactory
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } }
BeanDefinition 的覆蓋問題可能會有開發者碰到這個坑,就是在配置文件中定義 bean 時使用了相同的 id 或 name。
默認狀況下,allowBeanDefinitionOverriding 屬性爲 null(Boolean類型),若是在同一配置文件中重複了,會拋錯,可是若是不是同一配置文件中,會發生覆蓋。
循環引用也很好理解:A 依賴 B,而 B 依賴 A。或 A 依賴 B,B 依賴 C,而 C 依賴 A。
默認狀況下,Spring 容許循環依賴,固然若是你在 A 的構造方法中依賴 B,在 B 的構造方法中依賴 A 是不行的。
loadBeanDefinitions(beanFactory) 加載BeanDefinition
/** * Load bean definitions into the given bean factory, typically through * delegating to one or more bean definition readers. * @param beanFactory the bean factory to load bean definitions into * @throws BeansException if parsing of the bean definitions failed * @throws IOException if loading of bean definition files failed * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader */ protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException;
ClassPathXmlApplicationContext 是按照解析XML的加載方式。看javadoc的描述,是經過XmlBeanDefinitionReader來載入Bean Definitions。
/** * Loads the bean definitions via an XmlBeanDefinitionReader. * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader * @see #initBeanDefinitionReader * @see #loadBeanDefinitions */ @Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's // resource loading environment. beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // 初始化Reader 不重要,看下這個方法的javadoc就很好理解了 initBeanDefinitionReader(beanDefinitionReader); // 真正重要的步驟!! // 用Reader去加載XML配置 loadBeanDefinitions(beanDefinitionReader); }
loadBeanDefinitions(beanDefinitionReader)
/** * Load the bean definitions with the given XmlBeanDefinitionReader. * 看這句註釋:this method is just supposed to load and/or register bean definitions. */ protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { Resource[] configResources = getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); } String[] configLocations = getConfigLocations(); if (configLocations != null) { // 這個分支,經過路徑名去獲取Resource,會和上面的方法異曲同工 reader.loadBeanDefinitions(configLocations); } }
AbstractBeanDefinitionReader#loadBeanDefinitions(Resource... resources)
@Override public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException { Assert.notNull(resources, "Resource array must not be null"); int counter = 0; for (Resource resource : resources) { // 遍歷解析XML文件,加載 BeanDefinition counter += loadBeanDefinitions(resource); } return counter; }
接下去的源碼不細講,這裏載入分爲兩大步,
就是經過調用XML的解析器獲取到 document 對象,完成通用XML解析;
就是按照Spring的Bean規則進行解析。
Spring的Bean規則進行解析這個過程是BeanDefinitionDocumentReader來實現的,裏面包含了各類Spring Bean定義規則的處理。
這裏我以爲核心知識點就是Spring Bean規則的解析,簡單點來講,裏面包含了咱們在XML配置的那些信息,怎麼解析成容器中 BeanDefinition的規則和步驟。這部分因爲和主要流程關係不大。
在這由於Spring 的 Bean配置方式有不少,解析配置信息到BeanDefinition的實現方式也有不少,XML又是如今少用的方式,因此關於XML中的Spring Bean規則的解析的詳細源碼就先略過了。
咱們來看下prepareBeanFactory(beanFactory)這個方法
設置 BeanFactory的類加載器,添加幾個 BeanPostProcessor,手動註冊幾個特殊的 bean
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //設置類加載器,爲當前應用的application的類加載器 beanFactory.setBeanClassLoader(getClassLoader()); //爲bean工廠設置一個標準的SPEL表達式解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //爲bean工廠設置一個資源編輯器,爲了後面bean初始化時,給bean對象賦值 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //忽略如下接口的bean,這些bean都有set方法,不會對這些bean進行屬性賦值 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,就是從這裏註冊的獲取到的 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); //註冊事件監聽器的bean後置處理接口 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); //處理AOP的後置處理器 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } //註冊bean工廠的環境屬性 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
接下來分析postProcessBeanFactory(beanFactory);
這裏須要知道BeanFactoryPostProcessor 這個知識點,Bean 若是實現了此接口, 那麼在容器初始化之後,Spring 會負責調用裏面的 postProcessBeanFactory 方法。
提供給子類的擴展點,到這裏的時候,全部的Bean都加載、註冊完成了,可是都尚未初始化。
具體的子類能夠在這步的時候添加一些特殊的 BeanFactoryPostProcessor 的實現類或作點什麼事。
該方法沒有作實際的事情,主要是把ServletContextAwareProcessor後置處理器,給註冊進去。
實現ServletContextAware接口獲取上下文容器,就是從這裏注入的。
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { if (this.servletContext != null) { beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); } WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext); }
接下來分析invokeBeanFactoryPostProcessors(beanFactory);
調用BeanFactoryPostProcessor實現類 postProcessBeanFactory(factory) 方法
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //獲取FactoryPostProcessors,Spring內置的和本身設置的,而後供接下來的調用 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } } public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { //放入已經被處理過的bean Set<String> processedBeans = new HashSet<>(); //當前bean工廠是否實現了BeanDefinitionRegistry,若是有的話,則能夠註冊bean定義 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); //循環咱們傳入的bean工廠後置處理器,並加入處處理器集合中 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } //保存當前實例化的BeanDefinitionRegistryPostProcessor List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); //從bean工廠中獲取到繼承了BeanDefinitionRegistryPostProcessor的bean String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { //實例化優先級最高的BeanDefinitionRegistryPostProcessor if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //實例化出BeanDefinitionRegistryPostProcessor的類,咱們正常初始化這裏只有ConfigurationClassPostProcessor currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } //對實例化出來的BeanDefinitionRegistryPostProcessor進行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); //把實例化出來的BeanDefinitionRegistryPostProcessor添加進總的集合中供後面調用 registryProcessors.addAll(currentRegistryProcessors); //調用剛實例化出來的bean,註冊bean定義 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //清空調用後的BeanDefinitionRegistryPostProcessor currentRegistryProcessors.clear(); postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { //實例化實現了Ordered接口的BeanDefinitionRegistryPostProcessor if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); //調用沒有實現任何優先級接口的BeanDefinitionRegistryPostProcessor boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } //調用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); //調用本身實現的BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { //沒有實現BeanDefinitionRegistry接口的bean工廠,直接調用invokeBeanFactoryPostProcessors invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } //調用全部的BeanDefinitionRegistryPostProcessor完畢 //獲取容器中全部的 BeanFactoryPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); //執行全部BeanFactoryPostProcessor.postProcessBeanFactory方法,按照order接口排序 List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); //執行完成全部BeanFactoryPostProcessor.postProcessBeanFactory方法,清除全部緩存信息 beanFactory.clearMetadataCache(); } //咱們接下來主要是看ConfigurationClassPostProcessor調用postProcessBeanDefinitionRegistry方法 private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } }
接下來主要針對於,ConfigurationClassParser類進行解析操做處理
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { int registryId = System.identityHashCode(registry); if (this.registriesPostProcessed.contains(registryId)) { throw new IllegalStateException( "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry); } if (this.factoriesPostProcessed.contains(registryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + registry); } this.registriesPostProcessed.add(registryId); processConfigBeanDefinitions(registry); } public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); String[] candidateNames = registry.getBeanDefinitionNames(); //循環最開始初始化的全部bean定義 for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); //對配置類(帶有@Configuration標籤)進行標記,後續實例化時有用 if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) { if (logger.isDebugEnable()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } //進行標記,添加到配置類,候選集合中 else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } if (configCandidates.isEmpty()) { return; } //對全部配置類進行排序 configCandidates.sort((bd1, bd2) -> { int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); return Integer.compare(i1, i2); }); // 建立咱們經過@ComponentScan導入進來的bean name的生成器 // 建立咱們經過@Import導入進來的bean的名稱 SingletonBeanRegistry sbr = null; if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet) { BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton( AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR); if (generator != null) { this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } } if (this.environment == null) { this.environment = new StandardEnvironment(); } //建立一個類解析器 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates); Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size()); do { /**解析配置類,包括@Component、@ComponentScans等須要掃描的類,都會被解析出來放入bean定義容器 *@Configuration配置類爲full配置類,其餘的爲lite配置類 **/ parser.parse(candidates); parser.validate(); //獲取到解析出來的配置類 Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } //把全部@Import、@Bean解析出來的bean定義放入容器 this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames)); Set<String> alreadyParsedClasses = new HashSet<>(); for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } for (String candidateName : newCandidateNames) { if (!oldCandidateNames.contains(candidateName)) { BeanDefinition bd = registry.getBeanDefinition(candidateName); if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(new BeanDefinitionHolder(bd, candidateName)); } } } candidateNames = newCandidateNames; } } while (!candidates.isEmpty()); if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); } } //咱們再來看看ConfigurationClassPostProcessor.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { int factoryId = System.identityHashCode(beanFactory); if (this.factoriesPostProcessed.contains(factoryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + beanFactory); } this.factoriesPostProcessed.add(factoryId); if (!this.registriesPostProcessed.contains(factoryId)) { processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); } //這裏會修改@Configuration配置類的bean定義,到時候實例化bean時,會使用CGLIB建立動態代理,@Bean中調用獲取的bean都是容器中的bean,其餘配置類的bean,獲取的都是new出來的 enhanceConfigurationClasses(beanFactory); beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory)); }
講了bean定義的加載過程,如今咱們來說一下bean的實例化過程,bean的實例化,主要是finishBeanFactoryInitialization(beanFactory);這個方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //bean工廠建立轉化器 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } //實例化AOP相關的組件 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { //調用工廠實例化方法,這個方法咱們後面來分析 getBean(weaverAwareName); } beanFactory.setTempClassLoader(null); //凍結全部bean定義,在實例化時,不容許再修改bean定義 beanFactory.freezeConfiguration(); //實例化全部bean beanFactory.preInstantiateSingletons(); }
Spring IOC容器bean的實例化,到這基本就完成了,此次全部源代碼的分析把重要的地方,大體流程都講了一遍,可是有不少細節沒有講到,總體屬於框架整體深刻流程原理介紹。