Spring核心源碼:ApplicationContext

廢話

  1. spring版本:4.0.6
  2. 隨便作了這麼多年的spring,可是源碼就只閱讀過 shiro的。一直想去讀一下spring,mybatis,netty,這些結構優美的開源框架的源碼。

核心包:

  • spring-context:spring的上下文類,管理能夠看做是spring容器的主要管理者,及對外提供接口方。
    • ApplicationContext
  • spring-core:核心工具包,提供了環境、解析工具、建立工具。
  • spring-beans: bean對象建立、對象屬性加載
  • spring-aop:IOC注入工具
  • spring-expression:展現工具包,類型轉換,反射工具。

基本流程:

  • 1.建立beanFactory、BeanDefinition(一個bean的信息類)spring

  • (context)AbstractApplication.refresh():核心類型。初始化環境信息,加載配置路徑、實例化對象express

    • (context)AbstractApplication.prepareRefresh():加載環境信息
    • (context)AbstractApplication.obtainFreshBeanFactory():建立bean工程
      • (context)AbstractRefreshableApplicationContext.refreshBeanFactory():建立bean工廠DefaultListableBeanFactory(),接着調用loadBeanDefinitions()
        • (context)AbstractXmlApplicationContext.loadBeanDefinitions():實例化一個XML解析器(XmlBeanDefinitionReader),將環境信息和工廠加載進去,調用loadBeanDefinitions(),最後調用XmlBeanDefinitionReader.loadBeanDefinitions()出解析xml配置.
          • (bean)XmlBeanDefinitionReader.loadBeanDefinitiodins():先加載配置文件到內存,建立一個BeanDefinitionDocumentReader。在實例化bean對象
            • (bean)BeanDefinitionDocumentReader.registerBeanDefinitions():建立XmlReaderContext解析器,實例化bean對象
            • (bean)BeanDefinitionDocumentReader.parseBeanDefinitions():開始解析xml配置
            • (bean)BeanDefinitionDocumentReader.parseDefaultElement():解析import、alias、bean、beans配置,而後調用到DefaultListableBeanFactory.registerBeanDefinition()(bean建立類)
              • (bean)BeanDefinitionParserDelegate.parseBeanDefinitionElement():解析屬性並檢測,調用core層工具類。
                • (core)BeanDefinitionReaderUtils.createBeanDefinition():建立BeanDefinition,直接將類名加進去
              • (bean)DefaultListableBeanFactory.registerBeanDefinition():開始建立BeanDefinition,先給beanDefinitionMap加鎖,若是已經有了跳過,釋放鎖。而後resetBeanDefinition()建立
              • (bean)DefaultListableBeanFactory.resetBeanDefinition():先清理以前的BeanDefinition
    • (context)AbstractApplication.prepareBeanFactory():加載環境信息
    • (context)AbstractApplication.postProcessBeanFactory():加載環境信息
    • (context)AbstractApplication.invokeBeanFactoryPostProcessors():加載環境信息
    • (context)AbstractApplication.registerBeanPostProcessors():加載環境信息
    • (context)AbstractApplication.initMessageSource():加載環境信息
    • (context)AbstractApplication.initApplicationEventMulticaster():加載環境信息
    • (context)AbstractApplication.onRefresh():加載環境信息
    • (context)AbstractApplication.registerListeners():加載環境信息
    • (context)AbstractApplication.finishBeanFactoryInitialization():初始化bean
    • (context)AbstractApplication.finishRefresh():加載環境信息
    • (context)AbstractApplication.destroyBeans():加載環境信息
    • (context)AbstractApplication.cancelRefresh():加載環境信息
  • 2.實例化對象:AbstractApplication.finishBeanFactoryInitialization()mybatis

    • (context)AbstractApplicationContext.getBean():調用工廠,經過工廠根據名稱獲取代理對象。
      • (bean)DefaultListableBeanFactory.doGetBean():先檢測名稱,查看是否存在。
      • (bean)DefaultListableBeanFactory.doCreateBean()-->createBeanInstance():先檢測名稱,查看是否存在。
        • (bean)SimpleInstantiationStrategy.instantiate():經過class<?>.getDeclaredConstructor(),獲取目標bean的構造器
          • (bean)BeanUtils.instantiateClass():ctor.newInstance(args),實例化數據 直接實例化一個對象。
  • 注入:構造器注入、方法注入app

    • 構造器注入
      • 在 (bean)DefaultListableBeanFactory.doCreateBean()-->createBeanInstance() 中,檢測構造器是注入是否被使用。而後調用autowireConstructor()
        • new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
          • 直接檢測構造器類,根據引用beanFactory.getBean()獲取bean。若是沒有,直接走beanFactory.doGetBean()獲取
          • 直接在初始化的時候,將構造器數據傳入進去
    • 方法注入
      • 在構造器實例化以後,會直接調用 DefaultListableBeanFactory.doCreateBean()->populateBean()
      • 檢測Property的 ref,而後根據引用beanFactory.getBean()獲取bean。若是沒有,直接走beanFactory.doGetBean()獲取
      • 經過反射,獲取method。最後調用Method.invoke()注入進去
"模仿案例"
Class<?> ob = Class.forName("com.fxl.spring.test.SayServiceImpl");
SayService say = (SayService) ob.newInstance();
Method[] methodList = ob.getMethods();
for (Method method : methodList) {
	System.out.println(method.getName());
	if("setReflectNum".equals(method.getName())){
		method.invoke(say, new Integer(2));
	}
}
say.getMessage();

從說明開始:

ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:conf/Test.xml");
One one = (One) ctx.getBean("one");
System.out.println(one.getTwo().getName());
one.getDateTime();

通常,咱們開始學習spring的時候,都會從上面的使用模版開始。不管是誰都會告訴你第一行是生成一個beanFactroy的工廠,第二行就是從獲取須要的class對象。可是裏面發生了什麼,咱們並不瞭解。框架

  • ApplicationContext
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver

1.查看源碼,咱們發現是spring上下文的基本功能實現。查看說明eclipse

  • ApplicationContext:Central interface to provide configuration for an application. This is read-only while the application is running, but may be reloaded if the implementation supports this.
    • spring的上下文:爲spring提供核心的應用接口,當spring運行的時候,只能作讀操做。固然能夠從新唄加載<不能修改,只能從新建立>
//ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:conf/Test.xml");
1. ClassPathXmlApplicationContext:'記錄配置源'

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
	private Resource[] configResources;
}

2. AbstractXmlApplicationContext:'Context封裝的xml實現'
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
	private boolean validating = true;
}

3.'AbstractRefreshableConfigApplicationContext':'記錄配置信息'
public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
		implements BeanNameAware, InitializingBean {
	private String[] configLocations;
}

4. 'AbstractRefreshableApplicationContext':'refresh上下文的適配類型,用來建立beanfactory'
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {

	private Boolean allowBeanDefinitionOverriding;

	private Boolean allowCircularReferences;

	/** Bean factory for this context */
	// 默認的beanfactory
	private DefaultListableBeanFactory beanFactory;

	/** Synchronization monitor for the internal BeanFactory */
	private final Object beanFactoryMonitor = new Object();
}

5. 'AbstractApplicationContext':context的核心類、
    // 實例化spring-core的對象
    // refresh()刷新context
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext, DisposableBean {
	/** Logger used by this class. Available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());

	/** Unique id for this context, if any */
	private String id = ObjectUtils.identityToString(this);

	/** Display name */
	private String displayName = ObjectUtils.identityToString(this);

	/** Parent context */
	// 父類上下文
	private ApplicationContext parent;

	/** BeanFactoryPostProcessors to apply on refresh */
	private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors =
			new ArrayList<BeanFactoryPostProcessor>();

	/** System time in milliseconds when this context started */
	private long startupDate;

	/** Flag that indicates whether this context is currently active */
	private boolean active = false;

	/** Flag that indicates whether this context has been closed already */
	private boolean closed = false;

	/** Synchronization monitor for the "active" flag */
	// active鎖
	private final Object activeMonitor = new Object();

	/** Synchronization monitor for the "refresh" and "destroy" */
	private final Object startupShutdownMonitor = new Object();

	/** Reference to the JVM shutdown hook, if registered */
	private Thread shutdownHook;

	/** ResourcePatternResolver used by this context */
	// 資源加載匹配
	private ResourcePatternResolver resourcePatternResolver;

	/** LifecycleProcessor for managing the lifecycle of beans within this context */
	// 生命週期管理
	private LifecycleProcessor lifecycleProcessor;

	/** MessageSource we delegate our implementation of this interface to */
	//消息實現類
	private MessageSource messageSource;

	/** Helper class used in event publishing */
	//事件封裝類型
	private ApplicationEventMulticaster applicationEventMulticaster;

	/** Statically specified listeners */
	private Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();

	/** Environment used by this context; initialized by {@link #createEnvironment()} */
	// 環境配置:JVM環境
	private ConfigurableEnvironment environment;
}

6. DefaultResourceLoader: 類加載器
public class DefaultResourceLoader implements ResourceLoader {
	private ClassLoader classLoader;
}
  • EnvironmentCapable:All Spring application contexts are EnvironmentCapable, and the interface is used primarily for performing instanceof checks in framework methods that accept BeanFactory instances that may or may not actually be ApplicationContext instances in order to interact with the environment if indeed it is available.ide

    • 全部的spring都是環境功能,在若是須要和各類環境進行交互,當接受BeaFactory 實例,提供instanceof這一類的接口。<這個方法應該是用來屏蔽一些不一樣系統差別>
  • ListableBeanFactory:Extension of the BeanFactory interface to be implemented by bean factories that can enumerate all their bean instances, rather than attempting bean lookup by name one by one as requested by clients. BeanFactory implementations that preload all their bean definitions (such as XML-based factories) may implement this interface. (beanfactory的一個擴展接口)工具

  • HierarchicalBeanFactory:Sub-interface implemented by bean factories that can be part of a hierarchy.post

    • 由bean工廠實現的子接口,能夠做爲層次結構的一部分。
  • MessageSource:Strategy interface for resolving messages, with support for the parameterization and internationalization of such messages.學習

    • 解決消息的策略接口,支持參數化和此類消息的國際化。
  • ApplicationEventPublisher:Interface that encapsulates event publication functionality .(事件封裝)

  • ResourcePatternResolver:Strategy interface for resolving a location pattern (for example, an Ant-style path pattern) into Resource objects. (資源處理)

  • ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {
        super(parent);  //加載applicationContext
		setConfigLocations(configLocations);    //設置配置文件地址
		if (refresh) {
			refresh();  
		}
	}

debug進classPathXmlApplication裏面,發現最重要的是上上面這段代碼。用eclipse的crtl+T,咱們能夠看見繼承關係.主要是獲取一下applicationContext,而後將xml文件的路徑從新設置。最後經過AbstractApplicationContext 將配置從新加載到內存中。

  • AbstractApplicationContext

1.spring上下文的實現抽象類。用於application的合併,beanFactory的從新實現等等

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing. (刷新前)
			// 獲取JVM環境Environment,檢測啓動傳入的參數
			'prepareRefresh()'';

			// Tell the subclass to refresh the internal bean factory. 
			// 建立一個 beanfactory,將配置信息加載進去
			'ConfigurableListableBeanFactory' 'beanFactory' = 'obtainFreshBeanFactory()';

			// Prepare the bean factory for use in this context.(準備刷新的beanFactory)
			// 配置工廠的標準上下文特徵,例如上下文的類加載器和後處理器。
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.(容許子類中正在執行中的工廠)
				// 實例化並調用全部已註冊的BeanPostProcessor bean(事件bean),按照給定順序。處理一些示例化過程當中的業務邏輯,就像servlet的filter
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.(執行工廠做爲一個bean註冊到context中)
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.(註冊bean執行者攔截建立)
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.(初始化)
				initMessageSource();

				// Initialize event multicaster for this context.(初始化事件)
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.(初始化特別的的子類bean)
				onRefresh();

				// Check for listener beans and register them.(檢測監聽的bean,建立它們)
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.(實例化全部重名了的單例)
				// 完成這個上下文的bean工廠的初始化,初始化全部剩餘的單例bean。
				'finishBeanFactoryInitialization(beanFactory)';

				// Last step: publish corresponding event.(最後一步:發佈事件)
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.(摧毀bean)
				destroyBeans();

				// Reset 'active' flag.(從新設置時間的狀態)
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...(重置內存)
				resetCommonCaches();
			}
		}
	}
  • prepareRefresh:獲取JVM環境Environment,檢測啓動傳入的參數

  • ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory():加載並解析配置信息

  • prepareBeanFactory(beanFactory):將JVM環境所有傳入所有實例化放在 beanfactory中

  • postProcessBeanFactory(beanFactory):在它的標準初始化以後修改應用程序上下文的內部bean工廠。全部的bean定義都已經加載了,可是尚未實例化bean。這容許在特定的應用程序環境實現中註冊特殊的beanpost處理器等。(空方法)

  • invokeBeanFactoryPostProcessors(beanFactory):執行BeanPostProcessor,用於處理一些bean的示例

  • registerBeanPostProcessors(beanFactory):將BeanPostProcessor放入beanfactory中

  • initMessageSource():初始化message信息

  • initApplicationEventMulticaster():初始化applicationEventMulticaster,用來處理event事件。由哪一個listener來處理

  • onRefresh()

  • registerListeners():消息事件監聽器

  • finishBeanFactoryInitialization(beanFactory):將剩餘的bean實例化,存放在beanfactory的singletonObjects中。通常來講剩餘的都是配置文件中的信息

  • finishRefresh()

  • destroyBeans()

  • cancelRefresh(ex)

  • resetCommonCaches()

相關文章
相關標籤/搜索