Spring源码解析

ioc容器注入流程

ioc容器注入流程可以大致分为这几个步骤

image-20220606203347172

概述

  1. 在spring中我们的配置文件可能有很多种类型,例如:xmlpropertiesyml注解;这些类型的配置文件解析出来的东西肯定是不一样的,所以我们应该让他们通过一个抽象层BeanDefinitionReader,使其最终返回的结果都是BeanDefinition类型。对于不同的类型我们可以通过抽象层的不同的子类来对其进行解析

  2. 解析完成之后返回一个BeanDefinition对象,用于存储bean的定义信息。而这些BeanDefinition对象则存储在Map集合当中。之后通过BeanFactory实例化具体的对象

  3. BeanFactorybean工厂,用于访问一个 Spring bean 容器,相当于一个入口,也可以等同于容器

  4. PostProcessor称为后置处理器,也称为增强器。个人认为称为增强器更适合。PostProcessor有两个扩展分支,分别是BeanFactoryPostProcessorBeanPostProcessor,其主要的作用就是定制化我们的spring,使其具有更多的功能,类似于扩展点

  5. BeanFactoryPostProcessor针对BeanFactory进行增强;BeanPostProcessor针对Bean进行增强;例如我们常见的数据源配置${JDBC.userName},我们对配置文件进行解析之后得到的仍然还是${JDBC.userName}这个字符串,这时候就要用到BeanFactoryPostProcessor的实现类PlaceholdConfigurerSupport对其进行处理成我们想要的userName

  6. 我们可以在IOC容器里面的BeanFactory的标准初始化完成之后,修改IOC容器里面的这个BeanFactory也就是说,BeanFactoryPostProcessor的调用时机是在BeanFactory标准初始化之后,这样一来,我们就可以来定制和修改BeanFactory里面的一些内容了。那什么叫标准初始化呢?它说的是所有的bean定义已经被加载了,但是还没有bean被初始化

    说人话,就是BeanFactoryPostProcessor的调用时机是在BeanFactory标准初始化之后,这样一来,我们就可以来定制和修改BeanFactory里面的一些内容,此时,所有的bean定义已经保存加载到BeanFactory中了,但是bean的实例还未创建

    我们也可以自己创建一个类,实现BeanFactoryPostProcessor接口观察其什么时候被调用

  7. BeanFactory加载BeanDefinitionMap之中后就该通过反射去创建一个对象了。先通过反射实例化一个对象,之后进行初始化

  8. 初始化则遵从下图的几个步骤,调用完Aware接口之后就该调用各种BeanPostProcessor的实现类了,我们熟知的AOP就是实现了BeanPostProcessor接口

  9. 先调用BeanPostProcessor实现类的postProcessBeforeInitialization()方法,然后调用对象本身的构造方法,最后调用BeanPostProcessor实现类的postProcessAfterInitialization()方法

image-20220607195626582

源码

继承关系
AbstractApplicationContext
AbstractRefreshableApplicationContext
AbstractRefreshableConfigApplicationContext
AbstractXmlApplicationContext
ClassPathXmlApplicationContext

结合源码来观察注入的流程,以下面获得容器的方式为例

1
2
ApplicationContext applicationContext = 
new ClassPathXmlApplicationContext("config.xml");

上述代码会调用ClassPathXmlApplicationContext的有参构造器

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

这个构造器调用有三个参数的构造器

1
2
3
4
5
6
7
8
9
10
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {

super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}

至此,我们找到了自动注入中最重要的方法之一refresh(),而这个方法是从一个抽象类AbstractApplicationContext中继承来的,我们进入这个抽象方法中查看其源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

// Prepare this context for refreshing.
// 做一些准备工作
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
// 创建容器对象 DefaultListableBeanFactory
// 加载xml配置文件的属性到工厂中
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.
// 做额外的处理,由子类实现
postProcessBeanFactory(beanFactory);

StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// 调用各种BeanFactoryPostProcessor的实现类
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
// 注册BeanPostProcessor,这里只是注册,真正调用在getBean()方法
/**
* 从这里开始往下5个方法就是实例化前的最终步骤
*/
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();

// 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中,查找 监听bean(listener beans),并注册他们
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有非懒加载的单例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.
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();
contextRefresh.end();
}
}
}

我们可以看到创建容器和创建对象都是在这个方法中实现的

  1. refreshBeanFactory()方法在其实现类AbstractRefreshableApplicationContext中被重写,负责创建容器,并读取解析xml文件成一个个BeanDefinition对象,之后放到DefaultListableBeanFactory中的beanDefinitionMapbeanDefinitionName集合中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @Override
    protected final void refreshBeanFactory() throws BeansException {
    // 判断是否有BeanFactory
    if (hasBeanFactory()) {
    // 如果有则销毁并关闭
    destroyBeans();
    closeBeanFactory();
    }
    try {
    // 创建 DefaultListableBeanFactory
    DefaultListableBeanFactory beanFactory = createBeanFactory();
    beanFactory.setSerializationId(getId());
    customizeBeanFactory(beanFactory);
    // xml文件读取并解析
    // 解析完成后将BeanDefinition对象放到DefaultListableBeanFactory中的beanDefinitionMap和beanDefinitionName中
    loadBeanDefinitions(beanFactory);
    this.beanFactory = beanFactory;
    }
    catch (IOException ex) {
    throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
    }
  2. 调用各种BeanFactoryPostProcessor的实现类是在invokeBeanFactoryPostProcessors()方法中实现

  3. finishBeanFactoryInitialization()方法中调用了DefaultListableBeanFactory容器的preInstantiateSingletons()方法实例化各种非懒加载的单例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    @Override
    public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
    logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    // 为所有bean的名字创建一个List集合
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    // 触发所有非延迟加载单例bean的初始化,遍历集合的对象
    for (String beanName : beanNames) {
    // 合并父类BeanDefinition
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    //条件判断以下都是一些判断,getBean方法才去实例化
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    // 判断是否实现FactoryBean
    if (isFactoryBean(beanName)) {
    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
    // 进行类型转换
    if (bean instanceof FactoryBean) {
    FactoryBean<?> factory = (FactoryBean<?>) bean;
    boolean isEagerInit;
    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
    isEagerInit = AccessController.doPrivileged(
    (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
    getAccessControlContext());
    }
    else {
    isEagerInit = (factory instanceof SmartFactoryBean &&
    ((SmartFactoryBean<?>) factory).isEagerInit());
    }
    if (isEagerInit) {
    getBean(beanName);
    }
    }
    }
    else {
    // 如果beanName对应的bean不是FactoryBean,而是普通的bean,则通过beanName获取bean实例
    getBean(beanName);
    }
    }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
    Object singletonInstance = getSingleton(beanName);
    if (singletonInstance instanceof SmartInitializingSingleton) {
    StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
    .tag("beanName", beanName);
    SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    smartSingleton.afterSingletonsInstantiated();
    return null;
    }, getAccessControlContext());
    }
    else {
    smartSingleton.afterSingletonsInstantiated();
    }
    smartInitialize.end();
    }
    }
    }
  4. getBean(beanName)DefaultListableBeanFactory从父类AbstractBeanFactory继承的方法,其中又调用了doGetBean()方法,其中有一段代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // Create bean instance.
    // 创建bean实例
    if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, () -> {
    try {
    return createBean(beanName, mbd, args);
    }
    catch (BeansException ex) {
    // Explicitly remove instance from singleton cache: It might have been put there
    // eagerly by the creation process, to allow for circular reference resolution.
    // Also remove any beans that received a temporary reference to the bean.
    destroySingleton(beanName);
    throw ex;
    }
    });
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

    抽象方法createBean()即是要创建bean实例的方法

  5. 进入子类重写的createBean()方法中,其中有一段代码

    1
    2
    3
    4
    5
    6
    7
    8
    try {
    // 实际创建bean的方法
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isTraceEnabled()) {
    logger.trace("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
    }

    doCreateBean()就是实际创建bean实例的方法了

  6. 进入doCreateBean()方法中,有一段代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // Instantiate the bean.
    // BeanWrapper用来持有创建出来的bean对象
    BeanWrapper instanceWrapper = null;
    // 获取factoryBean实例缓存
    if (mbd.isSingleton()) {
    // 如果是单例对象,从factorybean实例缓存中移除当前bean定义信息
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    // 如果没有就创建实例
    if (instanceWrapper == null) {
    instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
    mbd.resolvedTargetType = beanType;
    }

    createBeanInstance()就是返回实例的方法

  7. 再进入createBeanInstance()中,有一段代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // Candidate constructors for autowiring?
    // 从bean后置处理器中为自动装配寻找构造方法,有且仅有一个有参构造或者有且仅有@Autowired注解构造
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    //满足
    // 存在可选构造方法
    // 自动装配模型为构造函数自动装配
    // 给BeanDefinition中设置了构造参数值
    // 有参与构造函数参数列表的参数
    //之一就进入if语句块
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
    mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
    return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
    return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    return instantiateBean(beanName, mbd);
  8. 再进入instantiateBean()中,有一段代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
    try {
    Object beanInstance;
    if (System.getSecurityManager() != null) {
    beanInstance = AccessController.doPrivileged(
    (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
    getAccessControlContext());
    }
    else {
    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
    }
    BeanWrapper bw = new BeanWrapperImpl(beanInstance);
    initBeanWrapper(bw);
    return bw;
    }
    catch (Throwable ex) {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
    }
  9. 再进入instantiate()中,其中有一段代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    		try {
    if (System.getSecurityManager() != null) {
    constructorToUse = AccessController.doPrivileged(
    (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
    }
    else {
    //获取默认的无参构造器
    constructorToUse = clazz.getDeclaredConstructor();
    }
    bd.resolvedConstructorOrFactoryMethod = constructorToUse;
    }
    catch (Throwable ex) {
    throw new BeanInstantiationException(clazz, "No default constructor found", ex);
    }
    }
    }
    return BeanUtils.instantiateClass(constructorToUse);

    我们终于可以看到我们熟悉的反射代码constructorToUse = clazz.getDeclaredConstructor(),通过这段代码获取了构造器,并在最后通过BeanUtils.instantiateClass(constructorToUse)最终实例化对象

  10. 进入BeanUtils.instantiateClass()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
try {
ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
return ctor.newInstance(argsWithDefaultValues);
}
}

ctor.newInstance(argsWithDefaultValues)通过反射的方式创建实例

  1. 最终将创建完成的bean实例返回到doCreateBean()方法中,doCreateBean()方法往下走到下面这段代码时候,对实例化的对象进行初始化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
    populateBean(beanName, mbd, instanceWrapper);
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
    if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    throw (BeanCreationException) ex;
    }
    else {
    throw new BeanCreationException(
    mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
    }
    }

    populateBean()方法就用于填充bean实例

    initializeBean()方法用于初始化bean实例

  2. 进入initializeBean()方法中,我们可以看到

    invokeAwareMethods:调用Aware接口的实现类

    applyBeanPostProcessorsBeforeInitialization():调用BeanPostProcessor的前置方法

    applyBeanPostProcessorsAfterInitialization():调用BeanPostProcessor的后置方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    invokeAwareMethods(beanName, bean);
    return null;
    }, getAccessControlContext());
    }
    else {
    invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
    invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
    throw new BeanCreationException(
    (mbd != null ? mbd.getResourceDescription() : null),
    beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
    }