Spring源码分析

Spring源码分析

Spring 是我们工作中最常用的框架,Spring使我们开发变得简单,工作几年只停留在使用 Spring 层面上,很多特性以及实现原理还知道,这次通过学习 Spring 源码加深自己对它的理解,同样学习优秀的框架可以学到很多设计理念。

前言

Spring 最重要的是 IoC(Inversion of Control) 容器,IOC 容器就是具有依赖注入功能的容器,IoC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中 new 相关的对象,应用程序由 IoC 容器进行组装。

下面这张图体现了 IoC 容器是如何装配一个 Bean 的,刚开始我们的解析配置(xml配置、注解配置)得到 BeanDefinition(Bean的定义信息),接着通过反射实例化,然后进行初始化得到一个完整的Bean,最后使用完成进行销毁。


@startuml
'left to right direction
'top to bottom direction
skinparam componentStyle rectangle
' scale 5/6

package "Define Config" as Config {
component "xml" as xml
component "annotation" as annotation
}

package "IOC Container" as IOC {

component "BeanDefinitation" as bd {

}
component "beanFactoryPostProcessor" as b {

card "beanFactoryPostProcessor"as b1
card "beanFactoryPostProcessor"as b2
card "beanFactoryPostProcessor"as b3
b1 -down-> b2
b2 -down-> b3
}

component "instantiation(实例化)" as inst{

}
component "initialization(初始化)" as init{

component "populateBean(填充属性)"as i1
component "执行各种Aware接口的set方法"as i2
component "执行BeanPostProcessor的\npostProcessBeforeInitialization方法"as i3
component "执行InitializingBean的\nafterPropertiesSet方法" as i4
component "执行自定义 init method" as i5
component "执行BeanPostProcessor的\npostProcessAfterInitialization" as i6
i1 -down-> i2
i2 -down-> i3
i3 -down-> i4
i4 -down-> i5
i5 -down-> i6
i6 -left-> beanSuccess

}
component "完整的Bean创建成功" as beanSuccess {

}

component "Destory(销毁)" as dest{
component "执行DisposableBean的destory方法"as d1
component "执行自定义destory method"as d2
beanSuccess -up-> d1
d1 -up-> d2
}
}

Config -down-> bd: 解析配置
bd -left-> b: 执行各种\nBeanFactoryPostProcessor
b -right-> bd
bd -down-> inst: 反射
inst -down-> i1
@enduml

ClassPathXmlApplicationContext

我们定义好一个cofig.xml 的配置,然后 ClassPathXmlApplicationContext 这个类就可以帮忙我们管理好我们定义好的 Bean,具体它是如何工作的呢,通过源码来分析。

public class ClassPathXmlApplicationTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("config.xml");
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
}
}

下图展示了 ClassPathXmlApplicationContext 继承关系。

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}

public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
// 调用父类构造器,最终会调用AbstractApplicationContext构造器
super(parent);
// 设置文件路径
setConfigLocations(configLocations);
// 默认刷新容器
if (refresh) {
refresh();
}
}
}

AbstractApplicationContext(调用父类构造器)

调用父类构造器,最终会调用AbstractApplicationContext构造器

public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {

// 一直调用到这里
public AbstractApplicationContext(ApplicationContext parent) {
this();
setParent(parent);
}

public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}

// 获取路径解析器
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
}

我们可以最终会创建一个 PathMatchingResourcePatternResolver ,是一个Ant通配符模式的 Resource 查找器,可以用来查找类路径或者文件系统的资源。

  • 加载单个资源
    • classpath:config.xml
    • http://www.baidu.com
  • 加载多个资源
    • classpath:META-INF/*.xml
    • file:/Users/config/*.xml

setConfigLocations(设置文件路径)

AbstractRefreshableConfigApplicationContext#setConfigLocations 方法

public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
implements BeanNameAware, InitializingBean {
// 设置配置文件,设置应用程序上下文
public void setConfigLocations(@Nullable String... locations) {
if (locations != null) {
Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
// 设置具体的路径
this.configLocations[i] = resolvePath(locations[i]).trim();
}
}
else {
this.configLocations = null;
}
}
// 解析路径
protected String resolvePath(String path) {
return getEnvironment().resolveRequiredPlaceholders(path);
}

}

resolvePath 主要用于解析占位符号的,替换路径中的占位符 ${placeholder} 为系统变量中的值。

Environment(环境变量)

解析路径占位符的时候会先获取环境变量 getEnvironment,具体代码:

public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
implements BeanNameAware, InitializingBean {
// 获取环境变量
public ConfigurableEnvironment getEnvironment() {
// 判断环境变量是否为空
if (this.environment == null) {
// 创建一个环境变量
this.environment = createEnvironment();
}
return this.environment;
}
// 创建一个标准的环境变量
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}
}

StandardEnvironment具体继承关系:

Enviroment主要代表了当前应用所处的环境,主要和 Profile 和 Property 相关。

refresh(默认刷新容器)

最终会调用到 AbstractApplicationContext#refresh 这个方法,这个方法比较重要,主要用于 bean 的解析。

AbstractApplicationContext#refresh

最终会调用到 AbstractApplicationContext#refresh 这个方法,这个方法比较重要,主要用于 bean 的解析。

public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}

}
}
}

prepareRefresh

激活开启容器,表示在真正做refresh操作之前需要准备做的事情:

  • 设置Spring容器的启动时间,撤销关闭状态,开启活跃状态。
  • 初始化属性源信息(Property)
  • 验证环境信息里一些必须存在的属性
  • 初始化一些事件集合

protected void prepareRefresh() {
// Switch to active.
// 当前激活时间
this.startupDate = System.currentTimeMillis();
// 设定当前容器未关闭
this.closed.set(false);
// 设置当前容器处于激活状态
this.active.set(true);
// 初始化一下属性(该方法默认是空的,是提供给子类来实现的,有些bean初始化需要一些依赖加载配置
// Initialize any placeholder property sources in the context environment.
initPropertySources();
// 校验熟悉是否合法
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();

// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}

obtainFreshBeanFactory

获取beanFactory,调用 AbstractRefreshableApplicationContext#refreshBeanFactory 方法,该方法实现对该上下文的底层bean工厂执行实际的刷新,关闭之前的bean工厂(如果有的话),并为上下文生命周期的下一阶段初始化一个新bean工厂。

@Override
protected final void refreshBeanFactory() throws BeansException {
// 若已经存在beanFactory了,那就做一些清理工作(销毁单例Bean、关闭工厂)
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 加载Bean定义。抽象方法,由子类去决定从哪儿去把Bean定义加载进来
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}

prepareBeanFactory

对beanFactory做预处理设置,对刚创建的BeanFactory进行相关的设置为后续的使用做准备

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());

// 设置 beanFactory 的表达式语言处理器,Spring3 增加了表达式语言的支持,如:@Value("#{19 - 1}")
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

// 为 beanFactory 增加一个默认的 propertyEditor,这个主要是对 bean 的属性等设置管理的一个工具,
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

// 添加 BeanPostProcessor,可以处理 XxAware 接口的 bean,让继承ApplicationContextAware的Bean能感知Bean
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

// 设置这几个忽略自动装配的接口,这基本不用能 @Autowire 注入
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);


// 设置这个几个可以自动装配
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

// 添加编译时支持AspectJ
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}

// 注入系统相关Bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}

postProcessBeanFactory

beanFactory准备工作完成后进行的后置处理工作,在标准初始化后,修改内部beanFactory,所有bean定义都加载加载完成,但是bean还没有被实例化。

这允许在特定的 ApplicationContext实现中注册特殊的 BeanPostProcessors等,其实这个时候拿到 beanFactory,可以对beanFactory做任何你想处理的东西。

一般web容器都会对应的实现此方法,比如 AbstractRefreshableWebApplicationContext,设置后置处理器或者一些环境变量相关的东西。

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

invokeBeanFactoryPostProcessors

执行beanFactory后置处理器的方法,在Spring容器中找出实现了BeanFactoryPostProcessor接口的processor并执行。最终会调用 PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法执行。

主要有看这两个接口:

  • BeanFactoryPostProcessor:用来修改Spring容器中已经存在的bean的定义,使用ConfigurableListableBeanFactory对bean进行处理
  • BeanDefinitionRegistryPostProcessor:继承BeanFactoryPostProcessor,作用跟BeanFactoryPostProcessor一样,只不过是使用BeanDefinitionRegistry对bean进行处理,带有注册功能,Spring注解驱动的 ConfigurationClassPostProcessor 就是实现这个处理器。

registerBeanPostProcessors

注册bean的后置处理器,此部分实质上是在BeanDefinitions中寻找BeanPostProcessor,之后调用BeanFactory#addBeanPostProcessor方法保存在一个List中,注意添加时仍然有优先级的概念,优先级高的在前面。

initMessageSource

初始化 MessageSource 组件,在Spring容器中初始化一些国际化相关的属性。

initApplicationEventMulticaster

初始化广播事件

onRefresh

用来初始化子容器中的bean,默认是空方法。

一个模板方法,不同的Spring容器做不同的事情,允许子类在进行bean初始化之前进行一些定制操作。

比如,AbstractRefreshableWebApplicationContext#onRefresh方法会初始化主题。

registerListeners

注册监听器

finishBeanFactoryInitialization

初始化所有剩下的单实例 bean

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 为容器初始化ConversionService,这个主要是做类型转化
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}

// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 若没有设置值解析器,那就注册一个默认的值解析器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}

// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}

// Stop using the temporary ClassLoader for type matching.
// 清空临时类加载器
beanFactory.setTempClassLoader(null);

// Allow for caching all bean definition metadata, not expecting further changes.
// 缓存(快照)下当前所有的Bean定义信息 beanFactory
beanFactory.freezeConfiguration();

// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有单例对象
beanFactory.preInstantiateSingletons();
}

finishRefresh

完成bean的创建初始化工作,完成 IoC 容器的创建

protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
// 表示清除一些resourceCaches,清除context级别的资源缓存,比如ASM的元数据
clearResourceCaches();

// Initialize lifecycle processor for this context.
// 初始化所有的LifecycleProcessor,与生命周期相关
initLifecycleProcessor();

// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();

// Publish the final event.
// 发布容器刷新的事件:
publishEvent(new ContextRefreshedEvent(this));

// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}

总结

参考

Comments