Spring源码阅读
1.Spring 容器几个重要的接口
org.springframework.core.env.Environment
Interface representing the environment in which the current application is running.
继承自org.springframework.core.env.PropertyResolver
Interface for resolving properties against any underlying source.
拥有PropertyResolver
,则有用crud properties的行为
Environment
对ActiveProfiles进行了支持
org.springframework.beans.factory.BeanFactory
The root interface for accessing a Spring bean container.
Bean container root接口
关于spring的spring bean的生命周期可以查看该接口的文档,有详细的描述
org.springframework.beans.factory.config.BeanDefinition
A BeanDefinition describes a bean instance, which has property values, constructor argument values, and further information supplied byconcrete implementations.
将xml,数据库等中的配置信息装载成一个一个的bean的BeanDefinition
其继承了两大接口
org.springframework.beans.BeanMetadataElement
Interface to be implemented by bean metadata elements
that carry a configuration source object.
org.springframework.core.AttributeAccessor
如其名现实该接口,拥有key-value的crud行为
org.springframework.beans.factory.support.BeanDefinitionReader
Simple interface for bean definition readers. Specifies load methods with Resource and String location parameters.
加载Definition资源,比如读取xml文件,对应实现类有XmlBeanDefinitionReader
org.springframework.beans.factory.config.BeanFactoryPostProcessor
Allows for custom modification of an application context's bean definitions, adapting the bean property values of the context's underlying bean factory.
主要用是对ConfigurableListableBeanFactory
进行预处理,可以理解为对BeanFactory进行一些回调处理
org.springframework.beans.factory.config.BeanPostProcessor
Factory hook that allows for custom modification of new bean instances,e.g. checking for marker interfaces or wrapping them with proxies.
主要是对SpringBean进行一些回调处理
org.springframework.context.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各种核心接口.
1.org.springframework.core.env.EnvironmentCapable
获取environment
的行为
2.org.springframework.beans.factory.ListableBeanFactory
对BeanFactory进行了拓展,如其名Listable
3.org.springframework.beans.factory.HierarchicalBeanFactory
4.org.springframework.context.MessageSource
5.org.springframework.context.ApplicationEventPublisher
事件发布行为
6.ResourcePatternResolver
拥有加载资源的行为
总结
:从抽象的层面讲,通过Spring容器初始化大概需要以上接口的实现参与,所有行为的执行者当然是ApplicationContext
Environment读取一些系统变量,例如System.getProperties()
BeanDefinitionReader加载资源,生成BeanDefinition
BeanFactory经过BeanFactoryPostProcessor回调处理
依照BeanDefinition转换为SpringBean(反射)
Spring的Bean经过BeanPostProcessor回调处理
PS
:以上几点没有时间上的发生顺序,也没有逻辑上的强关联,说得不是特别准确,但是从抽象的角度看,Spring容器的初始化大概会经历这几个流程节点.
2.Spring容器初始化
下面正式开始开始进行Spring的源码阅读,阅读源码的入口当然是ApplicationContext
,笔者选择AnnotationConfigApplicationContext
作为入口进行阅读,该对象是一个标准的spring上下文,接收annotated classes.
2.1 初始化AnnotationConfigApplicationContext
public class HelloSpring {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Cat bean = context.getBean(Cat.class);
}
}
实例代码非常简单,注入一个引导Object的class文件,获取Bean
2.2 AnnotationConfigApplicationContext实例化方法
实例代码使用的构造方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
下面就到了spring源码阅读起来恶心的地方,大量的使用了继承,当我通过该构造方法创建该对象的时候,Spring会先调用其父类的空参构造方法
自上而下说起
1.DefaultResourceLoader
初始化属性ClassLoader
2.AbstractApplicationContext
初始化属性resourcePatternResolver
3.GenericApplicationContext
初始化属性beanFactory
(DefaultListableBeanFactory)这个实现类也繁杂
4.1this
初始化属性AnnotatedBeanDefinitionReader
4.2this
初始化属性ClassPathBeanDefinitionScanner
简简单单一个this()大概会经历这些...
2.3this()详解
2.3.1DefaultResourceLoader
ResourceLoader
* Strategy interface for loading resources (e.. class path or file system
* resources). An {@link org.springframework.context.ApplicationContext}
* is required to provide this functionality, plus extended
* {@link org.springframework.core.io.support.ResourcePatternResolver} support.
一个加载资源的策略接口ApplicationContext
必须提供该行为
DefaultResourceLoader
是ResourceLoader
的默认实现
简单的说DefaultResourceLoader
就是讲路径(String类型)包装成Resource
,Resource
是一种输入流.
2.3.2AbstractApplicationContext
ApplicationContext的模板方法
extends:DefaultResourceLoader
类
implements:ConfigurableApplicationContext
接口
2.3.2.1ConfigurableApplicationContext
如其名,给上下文添加Configurable行为,其继承的接口有ApplicationContext
,Lifecycle
,Closeable
Lifecycle
:加入了start,stop的行为
Closeable
:继承自AutoCloseable
加入close的行为
ApplicationContext
:上文已介绍
回到正题AbstractApplicationContext
/*
* Create a new AbstractApplicationContext with no parent.
*/
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
创建一个ResourcePatternResolver
,用于资源加载
2.3.3GenericApplicationContext
通用的ApplicatonContext,对AbstractApplicationContext进一步具体化.
extends:AbstractApplicationContext
类
implements:BeanDefinitionRegistry
接口
2.3.3.1BeanDefinitionRegistry
用于保存Bean定义信息的注册表
继承AliasRegistry
:别名管理,可以进行别名注册
回到正题GenericApplicationContext
,创建一个BeanFactory
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
这个BeanFactory创建包含了大量需要去了解的地方,后面会专门开一个章节就行介绍,其继承关系如下
2.3.4AnnotationConfigApplicationContext
extends:GenericApplicationContext
implements:AnnotationConfigRegistry
2.3.4.1AnnotationConfigRegistry
提供了两个行为
/**
* Register one or more annotated classes to be processed.
* <p>Calls to {@code register} are idempotent; adding the same
* annotated class more than once has no additional effect.
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
void register(Class<?>... annotatedClasses);
/**
* Perform a scan within the specified base packages.
* @param basePackages the packages to check for annotated classes
*/
void scan(String... basePackages);
回到正题,该构造方法主要将连个属性进行实例化AnnotatedBeanDefinitionReader
,ClassPathBeanDefinitionScanner
下面介绍:AnnotatedBeanDefinitionReader
2.3.4.2AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
第一步:getOrCreateEnvironment
/**
* Get the Environment from the given registry if possible, otherwise return a new
* StandardEnvironment.
*/
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
//获取 environment
if (registry instanceof EnvironmentCapable) {
return ((EnvironmentCapable) registry).getEnvironment();
}
//创建一个environment,很明显,不会走到这一步,因为applicationContext继承了EnvironmentCapable,当然也是创建一个StandardEnvironment
return new StandardEnvironment();
}
第二部:this方法
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.registry = registry;
//根据注册器以及环境变量 创建条件鉴别器,主要使用@Conditional注解
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}