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()

相关文章
相关标签/搜索