文章目录
- 前言
- 一、启动过程
- 二、创建 Bean 容器,加载并注册 Bean
- 三、准备 Bean 容器
- 四、初始化所有的 singleton beans(lazy-init 的除外)
- 总结
前言
本文的源码分析部分参考自Spring IOC 容器源码分析
最近在看Spring源码,本来想全部看了后写文档总结,但怕后面懒不想写,就准备先写一篇。Spring是很多模块的集合,是一款开源的轻量级 Java 开发框架,旨在简化企业开发以及提高系统的可维护性。
Spring 最重要的概念是IoC 和 AoP,关于定义不再多做介绍,本文主要是介绍IoC源码部分。IoC中总体来说分为两部分,一个是创建 Bean 容器,一个是初始化 Bean。
全文的流程关系主要如下图所示,该图来自于马士兵教育Spring公开课的截图。
在启动容器后,会进入核心方法refresh(),在这个方法中首先会去创建beanfactory,我们能够在这个beanfactory中拿到beandefinitionMap等信息,之后会去调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory方法,注册一些回调函数,比如beanpostprocessor等一系列的操作。做完这些,会根据beanName调用doGetBean方法去获取bean,在这个过程,会先去缓存获取,如果缓存中没有,则会调用doCreatBean方法利用反射去创建bean。
接下来是源码分析。
一、启动过程
先上Spring 容器启动入口:
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationfile.xml");
}
通过传入配置文件来启动 Spring 的 ApplicationContext,ApplicationContext 启动过程中,会负责创建实例 Bean,往各个 Bean 中注入依赖等。那么我们从 ClassPathXmlApplicationContext 的构造方法说起。在构造方法中最重要的就是调用了refresh(),这是整个流程的核心。
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
private Resource[] configResources;
// 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
public ClassPathXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
...
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
// 设置配置文件
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
...
}
refresh()方法中包含大量的前置工作来注册加载对象,每一步的作用可以看注册,这里不会对每一步都进行讲解,挑选部分来讲。
@Override
public void refresh() throws BeansException, IllegalStateException {
// 加锁,防止refresh()还没结束,又出现启动或销毁容器的操作
synchronized (this.startupShutdownMonitor) {
// 容器刷新前的准备工作
//1、设置容器的启动时间
//2、设置活跃状态:true
//3、设置关闭状态:false
//4、获取Environment对象,并加载当前系统的属性值
//5、准备监听器和事件的集合
prepareRefresh();
// 创建容器对象:DefaultListableBeanFactory
// 加载xml文件到当前工厂,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 初始化BeanFactory
// 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
prepareBeanFactory(beanFactory);
try {
// BeanFactoryPostProcessor接口的postProcessBeanFactory方法
// 提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
postProcessBeanFactory(beanFactory);
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor的实现类,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
// 国际化
initMessageSource();
// 事件广播器
initApplicationEventMulticaster();
// 扩展点
onRefresh();
// 注册事件监听器
registerListeners();
// 初始化所有的 singleton beans(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
// 广播事件,ApplicationContext 初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经初始化的 singleton 的 Beans
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
二、创建 Bean 容器,加载并注册 Bean
在refresh() 方法中的 obtainFreshBeanFactory()会初始化 BeanFactory、加载 Bean、注册 Bean。需要注意的是Bean 实例并未在这一步生成,只是配置信息都提取出来了,即 beanDefinition。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 初始化BeanFactory,并进行xml文件读取,并将得到的BeanFactory记录在当前实体的属性中
refreshBeanFactory();
// 返回刚刚创建的 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
进入refreshBeanFactory();
@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果当前ApplicationContext有BeanFactory,销毁所有 Bean,关闭 BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 序列化
beanFactory.setSerializationId(getId());
// 自定义BeanFactory两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
customizeBeanFactory(beanFactory);
// 加载 Bean 到 BeanFactory 中
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
在上面的方法中有一步是 加载 Bean 到 BeanFactory 中即loadBeanDefinitions(beanFactory)。这个方法将根据配置,加载各个 Bean,然后放到 BeanFactory 中。读取配置的操作在 XmlBeanDefinitionReader 中,其负责加载配置、解析。
三、准备 Bean 容器
refresh()往下走,到了prepareBeanFactory(factory) 方法
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// BeanFactory 需要加载类,也就需要类加载器
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加一个 BeanPostProcessor,这个 processor 比较简单:
// 实现了 Aware 接口的 beans 在初始化的时候,这个 processor 负责回调
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 如果某个 bean 依赖于以下几个接口的实现类,因为还没有初始化,在自动装配的时候忽略它们,Spring 会通过invoke方式来处理这些依赖。
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//为特殊的几个 bean 赋值,如果有 bean 依赖了以下几个,会注入这边相应的值
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 在 bean 实例化后,如果是 ApplicationListener 的子类,注册事件监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
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()));
}
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());
}
}
四、初始化所有的 singleton beans(lazy-init 的除外)
refresh()方法来到了 finishBeanFactoryInitialization(beanFactory)。到目前为止,BeanFactory 已经创建完成,并且所有的实现了 BeanFactoryPostProcessor 接口的 Bean 都已经实例化并且其中的 postProcessBeanFactory(factory) 方法已经得到回调执行了。而且 Spring 已经“手动”注册了一些特殊的 Bean,如 environment、systemProperties 等。
如果没有设置懒加载,那么 Spring 会在接下来初始化所有的 singleton beans。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化名字为 conversionService 的 Bean。初始化的动作包装在 beanFactory.getBean(...) 中
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(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
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);
// 到这一步,Spring 已经开始预初始化 singleton beans 了,freezeConfiguration不希望这个时候还出现 bean 定义解析、加载、注册。
beanFactory.freezeConfiguration();
// 开始初始化
beanFactory.preInstantiateSingletons();
}
进入preInstantiateSingletons()
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// 保存了所有的beanDefinitionNames
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 下面这个循环,触发所有的非懒加载的 singleton beans 的初始化操作
for (String beanName : beanNames) {
// 合并父 Bean 中的配置,注意 <bean id="" class="" parent="" /> 中的 parent
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象、非懒加载的 singletons。如果配置了 'abstract = true',那是不需要初始化的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 处理 FactoryBean
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
// 对于普通的 Bean,只要调用 getBean(beanName) 这个方法就可以进行初始化了
getBean(beanName);
}
}
}
// 到这里说明所有的非懒加载的 singleton beans 已经完成了初始化
// 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
进入getBean(beanName)方法
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// getBean 方法用来从容器中获取 Bean 用,已经初始化过了就从容器中直接返回,否则就先初始化再返回
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 获取一个 “正统的” beanName,处理两种情况
// 一个是前面说的 FactoryBean(前面带 ‘&’),
// 一个是别名问题,因为这个方法是 getBean,获取 Bean 用的,你要是传一个别名进来,是完全可以的
final String beanName = transformedBeanName(name);
// 返回值
Object bean;
// 提前检查单例缓存中是否有手动注册的单例对象
Object sharedInstance = getSingleton(beanName);
// args 传参是 null,但是如果 args 不为空的时候,那么意味着调用方不是希望获取 Bean,而是创建 Bean
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("...");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 下面这个方法:如果是普通 Bean 的话,直接返回 sharedInstance,
// 如果是 FactoryBean 的话,返回它创建的那个实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 当对象是单例的时候会尝试解决循环依赖问题,但原型模式下存在循环依赖问题就会抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 获取父类容器
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 如果当前容器不存在这个 BeanDefinition,试试父容器中有没有
String nameToLookup = originalBeanName(name);
if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。
markBeanAsCreated(beanName);
}
// 准备创建 Bean ,对于 singleton 的 Bean 来说,容器中还没创建过此 Bean;对于 prototype 的 Bean 来说,本来就是要创建一个新的 Bean。
try {
// BeanDefinition对象的转换
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 如果存在依赖,优先实例化依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//注册依赖关系,方便销毁
registerDependentBean(dep, beanName);
getBean(dep);
}
}
// 如果是 singleton scope 的,创建 singleton 的实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 创建 Bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 如果是 prototype scope 的,创建 prototype 的实例
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
// 创建 Bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 如果不是 singleton 和 prototype 的话,需要委托给相应的实现类来处理
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
// 创建 Bean
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 检查类型
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
后面还有流程图中填充属性,设置aware接口,还有init-method 、BeanPostProcessor 接口等操作都在createBean(String beanName, RootBeanDefinition mbd, Object[] args)方法里面,这里展开太多,就不继续往下说了。
总结
Spring的代码量真的很大,每一个分支都能展开讲很多,有些地方我也不是很清楚,后面会继续补充。