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的信息类)

  • (context)AbstractApplication.refresh():核心类型。初始化环境信息,加载配置路径、实例化对象

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

    • (context)AbstractApplicationContext.getBean():调用工厂,通过工厂根据名称获取代理对象。
      • (bean)DefaultListableBeanFactory.doGetBean():先检测名称,查看是否存在。
      • (bean)DefaultListableBeanFactory.doCreateBean()-->createBeanInstance():先检测名称,查看是否存在。
        • (bean)SimpleInstantiationStrategy.instantiate():通过class<?>.getDeclaredConstructor(),获取目标bean的构造器
          • (bean)BeanUtils.instantiateClass():ctor.newInstance(args),实例化数据 直接实例化一个对象。
  • 注入:构造器注入、方法注入

    • 构造器注入
      • 在 (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上下文的基本功能实现。查看说明

  • 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.

    • 所有的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.

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

转载于:https://my.oschina.net/u/2246410/blog/1800738

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值