以classpathXmlApplication爲例html
入口方法包含3個部分,spring
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
1.繼承父類,沒什麼東西數組
2.設置配置文件多線程
3.執行refresh方法(關鍵)。下面咱們就這兩個方法看看內部實現post
設置配置文件,這塊其實沒什麼東西,就是給context對象設置一個configLocations的數組,咱們看一下context類的繼承關係ui
下面看重點的refresh方法this
1 public void refresh() throws BeansException, IllegalStateException { 2 synchronized (this.startupShutdownMonitor) {//鎖住一個對象,防止多線程同時執行初始化的操做 3 // Prepare this context for refreshing.準備上下文,這裏設置一下開始實現,準備propery等 4 prepareRefresh(); 5 6 // Tell the subclass to refresh the internal bean factory. 7 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 8 9 // Prepare the bean factory for use in this context. 10 prepareBeanFactory(beanFactory); 11 12 try { 13 // Allows post-processing of the bean factory in context subclasses. 14 postProcessBeanFactory(beanFactory); 15 16 // Invoke factory processors registered as beans in the context. 17 invokeBeanFactoryPostProcessors(beanFactory); 18 19 // Register bean processors that intercept bean creation. 20 registerBeanPostProcessors(beanFactory); 21 22 // Initialize message source for this context. 23 initMessageSource(); 24 25 // Initialize event multicaster for this context. 26 initApplicationEventMulticaster(); 27 28 // Initialize other special beans in specific context subclasses. 29 onRefresh(); 30 31 // Check for listener beans and register them. 32 registerListeners(); 33 34 // Instantiate all remaining (non-lazy-init) singletons. 35 finishBeanFactoryInitialization(beanFactory); 36 37 // Last step: publish corresponding event. 38 finishRefresh(); 39 } 40 41 catch (BeansException ex) { 42 if (logger.isWarnEnabled()) { 43 logger.warn("Exception encountered during context initialization - " + 44 "cancelling refresh attempt: " + ex); 45 } 46 47 // Destroy already created singletons to avoid dangling resources. 48 destroyBeans(); 49 50 // Reset 'active' flag. 51 cancelRefresh(ex); 52 53 // Propagate exception to caller. 54 throw ex; 55 } 56 57 finally { 58 // Reset common introspection caches in Spring's core, since we 59 // might not ever need metadata for singleton beans anymore... 60 resetCommonCaches(); 61 } 62 } 63 }
這個代碼有點長,咱們把每一個方法幹什麼先研究一下,在深刻看每一個方法怎麼實現的。spa
從7行開始看,這個方法是爲了一個refreshBeanFactory。返回的類是ConfigurableListableBeanFactory,而這個factory是一個接口,咱們待會看看這個接口有哪些實現,先看看這個方法內部實現線程
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
咱們看到最後return的beanFactory就是ConfigurableListableBeanFactory。而這個接口只有一個default實現類DefaultListableBeanFactory。咱們看看這個類主要有哪些成員變量debug
1 private boolean allowEagerClassLoading = true; 2 3 /** Optional OrderComparator for dependency Lists and arrays */ 4 private Comparator<Object> dependencyComparator; 5 6 /** Resolver to use for checking if a bean definition is an autowire candidate */ 7 private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver(); 8 9 /** Map from dependency type to corresponding autowired value */ 10 private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<Class<?>, Object>(16); 11 12 /** Map of bean definition objects, keyed by bean name */ 13 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256); 14 15 /** Map of singleton and non-singleton bean names, keyed by dependency type */ 16 private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64); 17 18 /** Map of singleton-only bean names, keyed by dependency type */ 19 private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64); 20 21 /** List of bean definition names, in registration order */ 22 private volatile List<String> beanDefinitionNames = new ArrayList<String>(256); 23 24 /** List of names of manually registered singletons, in registration order */ 25 private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16); 26 27 /** Cached array of bean definition names in case of frozen configuration */ 28 private volatile String[] frozenBeanDefinitionNames; 29 30 /** Whether bean definition metadata may be cached for all beans */ 31 private volatile boolean configurationFrozen = false;
這些成員變量有機會咱們一個個分析下,咱們知道每一個bean 有一個beanDefinition對象來定義。在13行,咱們看到有一個BeanDefinition的Map,咱們隨便調試一下,看看這個裏面存了什麼東西。
這裏面居然只有7個對象,分別是:ConfigurationClassPostProcessor、DefaultEventListenerFactory、MessageResolver、EventListenerMethodProcessor、AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PropertiesFactoryBean、RequiredAnnotationBeanPostProcessor。這七個對象怎麼來的呢,舉個例子來看ConfigurationClassPostProcessor,這個類說明是,當配置文件中
Registered by default when using {@code <context:annotation-config/>} or
* {@code <context:component-scan/>}有這兩個配置的時候,便會注入這麼個類。好吧,那咱們看看在哪裏register的。咱們猜想是在
refreshBeanFactory();這個方法裏面。那看看這個方法
1 protected final void refreshBeanFactory() throws BeansException { 2 if (hasBeanFactory()) { 3 destroyBeans(); 4 closeBeanFactory(); 5 } 6 try { 7 DefaultListableBeanFactory beanFactory = createBeanFactory(); 8 beanFactory.setSerializationId(getId()); 9 customizeBeanFactory(beanFactory); 10 loadBeanDefinitions(beanFactory); 11 synchronized (this.beanFactoryMonitor) { 12 this.beanFactory = beanFactory; 13 } 14 } 15 catch (IOException ex) { 16 throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); 17 } 18 }
咱們看到第7行,建立了一個DefaultListableBeanFactory ,第10行有loadBeanDefinition。應該是在這裏處理的。咱們仍是先調試下看看。執行7行代碼,這個時候beanDefinitionMap是空的。執行完10行代碼,咱們的beanDefinitionMap有值了。這裏面爲了加深理解,咱們在咱們的spring-config.xml文件中加一個bean看看會怎麼樣。原來的spring-config.xml文件以下
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:util="http://www.springframework.org/schema/util" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 9 http://www.springframework.org/schema/context 10 http://www.springframework.org/schema/context/spring-context-4.1.xsd 11 http://www.springframework.org/schema/util 12 http://www.springframework.org/schema/util/spring-util-4.1.xsd"> 13 14 <context:annotation-config/> 15 16 <context:component-scan base-package="com.newbie.common"></context:component-scan> 17 18 <util:properties id="systemProperties" location="classpath:conf/user.properties" /> 19 20 21 </beans>
咱們隨便加一個bean,以下圖所示,有多個一個beanDefinition。因此這個地就是定義因此beanDefinition的入口,而咱們從autowire的bean是由相關processor處理的,這個從此若是有時間的話,咱們在分析。咱們繼續往下看
咱們回到原來的refresh方法裏面。
1 public void refresh() throws BeansException, IllegalStateException { 2 synchronized (this.startupShutdownMonitor) { 3 // Prepare this context for refreshing. 4 prepareRefresh(); 5 6 // Tell the subclass to refresh the internal bean factory. 7 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 8 9 // Prepare the bean factory for use in this context. 10 prepareBeanFactory(beanFactory); 11 12 try { 13 // Allows post-processing of the bean factory in context subclasses. 14 postProcessBeanFactory(beanFactory); 15 16 // Invoke factory processors registered as beans in the context. 17 invokeBeanFactoryPostProcessors(beanFactory); 18 19 // Register bean processors that intercept bean creation. 20 registerBeanPostProcessors(beanFactory); 21 22 // Initialize message source for this context. 23 initMessageSource(); 24 25 // Initialize event multicaster for this context. 26 initApplicationEventMulticaster(); 27 28 // Initialize other special beans in specific context subclasses. 29 onRefresh(); 30 31 // Check for listener beans and register them. 32 registerListeners(); 33 34 // Instantiate all remaining (non-lazy-init) singletons. 35 finishBeanFactoryInitialization(beanFactory); 36 37 // Last step: publish corresponding event. 38 finishRefresh(); 39 } 40 41 catch (BeansException ex) { 42 if (logger.isWarnEnabled()) { 43 logger.warn("Exception encountered during context initialization - " + 44 "cancelling refresh attempt: " + ex); 45 } 46 47 // Destroy already created singletons to avoid dangling resources. 48 destroyBeans(); 49 50 // Reset 'active' flag. 51 cancelRefresh(ex); 52 53 // Propagate exception to caller. 54 throw ex; 55 } 56 57 finally { 58 // Reset common introspection caches in Spring's core, since we 59 // might not ever need metadata for singleton beans anymore... 60 resetCommonCaches(); 61 } 62 } 63 }
咱們如今知道第7行返回的這個ConfigurableListableBeanFactory 有咱們全部的beanDefintion。這個方法是給ConfigurableListableBeanFactory 設置了若干預設變量,如今咱們也不清楚這個變量是幹嗎的,咱們先跳過這個方法,等回頭再分析他。
第14行postProcessBeanFactory(ConfigurableListableBeanFactory )。咱們看看這個代碼是作什麼事情,咱們有一個關注點,咱們@autowired的bean是怎麼被處理的。這個代碼,會根據不一樣context子類加入不一樣Processors,這個咱們也暫時不分析他,等回頭再看
第17行invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory )。這個方法應該就是能看到bean是如何建立的。這個代碼比較長,咱們先把調用關係簡單畫出來
執行invokeBeanFactoryPostProcessors以後,這裏主要是講各個processors類註冊進去,這裏須要得到具體的bean了,根據beanName和BeanDefinition。如何得到bean,經過DefaultListableBeanFactory的getBean方法,這裏判斷bean是單利仍是原型的,進入不一樣的getBean的邏輯,以後調用的AbstractAutowireCapableBeanFactory的createBean方法,以後經過反射來得到對應的bean。注意看一下doCreateBean方法裏面的populateBean()方法,這裏可以完成對屬性的注入。
上面這個方法,咱們調用的時候發現就註冊了一個ConfigurationClassPostProcessor,也不知道幹嗎的。後來經過搜索瞭解到這個方法主要是用於處理spring的後置處理器的相關內容,參考https://www.cnblogs.com/sishang/p/6588542.html和https://www.cnblogs.com/sishang/p/6576665.html。