Spring-IOC整体设计与源码分析

最近读完《Spring技术内幕》一书,虽然此书评价貌似不高,但边看书边读源码,感觉还是有点收获,至少为阅读Spring源码提供了思路。然后这篇文章就记录一下这几天看Spring IOC这块的源码以及整体思路。

1、 BeanFactory与ApplicationContext

在Spring的IOC容器设计中,主要由两个容器系列:

  • 实现BeanFactory接口的简单容器,提供了完整IoC容器服务支持,默认延迟初始化(lazy-load)——只有访问托管对象的时候,才会对对象进行初始化和依赖注入操作。
  • 实现ApplicationContext接口的集成容器,在BeanFactory的基础上增加了更多复杂的企业级功能,容器启动时,就默认把所有的单例对象实例化完成。

BeanFactory

2、 最简单的容器StaticListableBeanFactory

整个Spring容器中最简单的实现就是StaticListableBeanFactory,从它开始分析最合适不过了。

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
85
86
87
88
89
90
91
92
93
public class StaticListableBeanFactory implements ListableBeanFactory {

/** <BeanName, BeanInstance>的映射 */
private final Map<String, Object> beans;

// 默认构造会创建一个空的Map,自行调用addBean方法添加到容器中
public StaticListableBeanFactory() {
this.beans = new LinkedHashMap<String, Object>();
}

// 由外部预初始化一个Map
public StaticListableBeanFactory(Map<String, Object> beans) {
Assert.notNull(beans, "Beans Map must not be null");
this.beans = beans;
}

// addBean就是简单的将name和instance加入到Map中
public void addBean(String name, Object bean) {
this.beans.put(name, bean);
}

// 根据beanName从容器中获取Bean对象
@Override
public Object getBean(String name) throws BeansException {
// 处理"&"开头的BeanName(dereference解引用)
String beanName = BeanFactoryUtils.transformedBeanName(name);
Object bean = this.beans.get(beanName);

if (bean == null) {
// Bean不存在
throw new NoSuchBeanDefinitionException(beanName,
"Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]");
}

if (BeanFactoryUtils.isFactoryDereference(name) && !(bean instanceof FactoryBean)) {
// BeanName以"&"开头,但Bean不是FactoryBean
throw new BeanIsNotAFactoryException(beanName, bean.getClass());
}

if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
// Bean是FactoryBean,但BeanName不是"&"开头,则由FactoryBean创建Bean对象
try {
return ((FactoryBean<?>) bean).getObject();
}
catch (Exception ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
}
else {
// 其他情况直接返回Bean
return bean;
}
}

// 其余getBean方法(byName,byType)最终都是调用上面的getBean方法
...

// 判断bean是否为共享单例,也就是说调用getBean方法会始终返回同一个对象
// 注意:返回false,不一定说明是prototype的Bean,应该调isPrototype去显示检查是否是原型对象
@Override
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
Object bean = getBean(name);
return (bean instanceof FactoryBean && ((FactoryBean<?>) bean).isSingleton());
}

// 判断bean是否为原型实例,也就是说调用getBean方法会始终返回一个独立的新实例
// 注意:返回false,不应定说明是singleton的Bean,应该调isSingleton去显示检查是否是单例对象
@Override
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
Object bean = getBean(name);
return ((bean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) bean).isPrototype()) ||
(bean instanceof FactoryBean && !((FactoryBean<?>) bean).isSingleton()));
}

// 获取Bean的类型
@Override
public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
String beanName = BeanFactoryUtils.transformedBeanName(name);

Object bean = this.beans.get(beanName);
if (bean == null) {
throw new NoSuchBeanDefinitionException(beanName,
"Defined beans are [" + StringUtils.collectionToCommaDelimitedString(this.beans.keySet()) + "]");
}

if (bean instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
// 如果是FactoryBean, 去看Factory创建的是什么类型的Bean.
return ((FactoryBean<?>) bean).getObjectType();
}
return bean.getClass();
}
...
}

3、 特殊的Bean对象——FactoryBean

Spring容器中有两种Bean:普通Bean和工厂Bean。Spring直接使用前者,后者以工厂模式生产Bean对象,并由Spring管理。

Spring设计FactoryBean的目的是为了将复杂对象的相关构造逻辑封装在类中,比如常见的ProxyFactoryBean。

另外一个目的是为了让我们能将依赖注入到一些第三方库的对象中,比如LocalContainerEntityManagerFactoryBean负责JPA的EntityManagerFactory的创建,ThreadPoolExecutorFactoryBean负责线程池的创建,ForkJoinPoolFactoryBean负责ForkJoinPool线程池的创建,ScheduledExecutorFactoryBean负责调度线程池的创建…

但是Spring3.0基于Java注解的配置开始流行之后,这些FactoryBean基本都用不到了,这些对象我们可以通过@Bean方法的形式配置。

我个人大胆的猜测,FactoryBean是为了早期以XML配置对象的方式而设计的。

通过在BeanName前加上&前缀我们能拿到FactoryBean工厂本身。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MyBeanFactoryBean implements FactoryBean<MyBean> {

public MyBean getObject() throws Exception {
return new MyBean();
}

public Class<?> getObjectType() {
return MyBean.class;
}
}

// 直接通过beanName获取的是工厂创建的MyBean对象
beanFactory.getBean("myBean");
// 加&前缀获取的是MyBeanFactoryBean这个工厂本身
beanFactory.getBean("&myBean");

经常被问的一个问题是BeanFactory与FactoryBean的区别,用一句话总结起来:

BeanFactory代表Spring容器,而FactoryBean表示工厂类,其创建的对象被获取后作为容器中的Bean注册

4、 核心容器DefaultListableBeanFactory

Spring IOC体系结构中最核心的容器实现类就是DefaultListableBeanFactory,它实现了ConfigurableListableBeanFactoryBeanDefinitionRegistry两个接口的功能。

DefaultListableBeanFactory

4.1 、BeanDefinition、BeanDefinitionRegistry、BeanDefinitionReader

BeanDefinition用于描述一个Bean实例的scope、是否为懒加载、生命周期方法(init、destroy)、属性值、构造参数值以及组件依赖等信息。

BeanDefinition

BeanDefinitionRegistry就是BeanDefinition的注册表,提供了registerBeanDefinition(beanName, beanDefinition)removeBeanDefinition(beanName)等相关方法。

BeanDefinitionRegistry

BeanDefinitionReader负责从Properties、Xml、Groovy等配置文件中读取BeanDefinition,并将其注册到BeanDefinitionRegistry中。

BeanDefinitionReader

4.2、基于Java注解的配置

AnnotationConfigRegistry

Spring3.0之前只支持@Component、@Controller、@Service、@Repository这几个组件级的注解。

Spring3.0开始支持Java注解配置Bean对象,也就是通过@Configuration配置类中方法上的@Bean注解来定义Bean对象。

其中Bean被加入到Spring容器有两种方式:

1、register()方法直接以组件类的方式注册AnnotatedGenericBeanDefinition到容器中,具体实现在AnnotatedBeanDefinitionReader中;

2、scan()方法通过扫描包下的所有组件类以批量的方式注册若干个ScannedGenericBeanDefinition到容器中,具体实现在ClassPathBeanDefinitionScanner中;

如果注册的是@Configuration注解的类,则在ConfigurationClassPostProcessor处理器中将所有@Bean注解方法的Bean注册到容器中,这部分内容后面会讲BeanFactoryPostProcessor的时候再详细解析。

5、可配置的ConfigurableListableBeanFactory

ConfigurableListableBeanFactory

ConfigurableListableBeanFactory结合了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory三个接口的功能。这三个接口也分别代表了Spring容器提供的三大基本功能:

ListableBeanFactory:根据类型或注解查找Bean

AutowireCapableBeanFactory:解析Bean的依赖关系并进行自动装配

ConfigurableBeanFactory:为容器提供了配置接口,以拓展容器的功能

我们想要拓展Spring IOC容器的功能主要就是通过ConfigurableBeanFactory开出的几个接口实现的:

5.1、BeanExpressionResolver

ConfigurableBeanFactory有两个关于Spring EL表达式的方法:

1
2
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
BeanExpressionResolver getBeanExpressionResolver();

在Spring中BeanExpressionResolver的实现是StandardBeanExpressionResolver

BeanExpressionResolver

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
public class StandardBeanExpressionResolver implements BeanExpressionResolver {
/// ...
/** 该方法用于解析Spring EL表达式 **/
public Object evaluate(@Nullable String value, BeanExpressionContext evalContext) throws BeansException {
if (!StringUtils.hasLength(value)) {
return value;
}
try {
Expression expr = this.expressionCache.get(value);
if (expr == null) {
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);
this.expressionCache.put(value, expr);
}
StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
if (sec == null) {
sec = new StandardEvaluationContext(evalContext);
///...做了一堆的配置
customizeEvaluationContext(sec);
this.evaluationCache.put(evalContext, sec);
}
return expr.getValue(sec);
}
catch (Throwable ex) {
throw new BeanExpressionException("Expression parsing failed", ex);
}
}

// StandardBeanExpressionResolver提供了一个方法允许我们进行重载
protected void customizeEvaluationContext(StandardEvaluationContext evalContext) {
}
}

StandardBeanExpressionResolver提供了一个customizeEvaluationContext方法允许我们重载,我们唯一能做的就是对StandardEvaluationContext进行一些自定义配置。

5.2、Scope

Spring容器为我们提供了SCOPE_SINGLETONSCOPE_PROTOTYPE两种基本的Scope,它还允许我们注册自己的Scope。比如Web应用中会用到的requestsession两个Scope,另外Spring还提供了很多基础的Scope给我们,如线程级别SimpleThreadScope、事务级别的SimpleTransactionScope

Spring提供的Scope

通常我们往容器中注册Scope只需调用beanFactory.registerScope方法即可,另外Spring提供了一个BeanFactoryPostProcessor给我们——CustomScopeConfigurer。

关于BeanFactoryPostProcessor后面有一部分会介绍。

5.3、ConversionService

ConversionService,顾名思义,就是Spring提供给我们的类型转换服务。它主要有几种用途,解析配置文件中字符串,解析BeanDefinition中的property并绑定到对象中(DataBinder),解析Web应用中的请求参数并绑定到Controller的入参对象中(WebDataBinder),解析Spring EL表达式中的字面量。

ConversionService

除了ConversionService,ConfigurableBeanFactory还提供了PropertyEditorRegistrarTypeConverterStringValueResolver等接口用于处理Bean对象和类型转换。

关于Spring Converter的内容可以参考这几篇教程:

https://www.baeldung.com/spring-type-conversions

https://www.baeldung.com/spring-mvc-custom-data-binder

https://www.baeldung.com/spring-mvc-custom-property-editor

5.4、BeanPostProcessor

这个接口是用于扩展Spring功能的核心接口,事实上Spring容器本身的很多功能特性就是通过这个接口丰富的。

BeanPostProcessor有两个方法:

1
2
3
4
5
6
public interface BeanPostProcessor {
// 初始化方法之前调用
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
// 初始化方法之后调用
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

很明显我们只要找到SpringBean什么时候初始化,就知道这两个方法什么时候被调用,Spring Bean的初始化分为四步:

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
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/// ...
/// 这里是整个初始化过程的代码
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 第一步:调用Aware方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}

// 第二步:调用BeanPostProcessor的postProcessBeforeInitialization方法
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);
}
// 第四步:调用BeanPostProcessor的postProcessAfterInitialization方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}
///...
}
  1. 第一步:调用Aware方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    private void invokeAwareMethods(final String beanName, final Object bean) {
    /// 如果bean对象实现了相应的Aware接口,那这里会调用三种Aware方法:
    /// BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
    if (bean instanceof Aware) {
    if (bean instanceof BeanNameAware) {
    ((BeanNameAware) bean).setBeanName(beanName);
    }
    if (bean instanceof BeanClassLoaderAware) {
    ClassLoader bcl = getBeanClassLoader();
    if (bcl != null) {
    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
    }
    }
    if (bean instanceof BeanFactoryAware) {
    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
    }
    }
    }
  1. 第二步:调用BeanPostProcessor.postProcessBeforeInitialization方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    throws BeansException {
    /// 这个很简单:就是拿到BeanFactory里的所有BeanPostProcessor
    /// 然后依次调用postProcessBeforeInitialization方法
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
    Object current = processor.postProcessBeforeInitialization(result, beanName);
    if (current == null) {
    return result;
    }
    result = current;
    }
    return result;
    }
  1. 第三步:调用bean对象的init方法

    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
    protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
    throws Throwable {

    /// 先看有没有实现Spring定义的InitializingBean接口
    /// 如果有的话就调用InitializingBean的afterPropertiesSet方法
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
    if (logger.isTraceEnabled()) {
    logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
    }
    if (System.getSecurityManager() != null) {
    try {
    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
    ((InitializingBean) bean).afterPropertiesSet();
    return null;
    }, getAccessControlContext());
    }
    catch (PrivilegedActionException pae) {
    throw pae.getException();
    }
    }
    else {
    ((InitializingBean) bean).afterPropertiesSet();
    }
    }

    /// 然后调用自定义的init方法
    /// 这个init方法是xml或@Bean注解配置的init-method属性
    if (mbd != null && bean.getClass() != NullBean.class) {
    String initMethodName = mbd.getInitMethodName();
    if (StringUtils.hasLength(initMethodName) &&
    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
    !mbd.isExternallyManagedInitMethod(initMethodName)) {
    invokeCustomInitMethod(beanName, bean, mbd);
    }
    }
    }

    这里也许会有人想到使用JSR-250规范中定义的@PostConstruct注解进行初始化。

    Spring提供了CommonAnnotationBeanPostProcessorInitDestroyAnnotationBeanPostProcessor来处理JavaEE标准中的注解,如@PostConstruct、@PreDestroy、@Resource。

    在InitDestroyAnnotationBeanPostProcessor中可以看到它是通过实现BeanPostProcessor#postProcessBeforeInitialization方法并在其中调用Bean的@PostConstruct注解方法的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
    /// 这里的initMethod就是通过@PostConstruct注解解析出来的方法
    metadata.invokeInitMethods(bean, beanName);
    }
    catch (InvocationTargetException ex) {
    throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
    }
    catch (Throwable ex) {
    throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
    }
    return bean;
    }

    所以关于初始化方法的调用顺序是:

    @PostConstruct==>InitializingBean.afterPropertiesSet==>Xml或@Bean中定义的init-method

    而且Bean中@PostConstruct方法可以定义多个,但InitializingBean因为是接口所以afterPropertiesSet只有一个方法,init-method也只能有一个。

    关于Spring初始化的过程可以参考这篇教程

  2. 第四步:调用BeanPostProcessor.postProcessAfterInitialization方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {
    /// 这个很简单:就是拿到BeanFactory里的所有BeanPostProcessor
    /// 然后依次调用postProcessBeforeInitialization方法
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
    Object current = processor.postProcessAfterInitialization(result, beanName);
    if (current == null) {
    return result;
    }
    result = current;
    }
    return result;
    }

用一张图总结一下:

initializeBean

5.5、BeanPostProceesor的常见实现

BeanPostProceesorImpl

Spring内部实现各种Aware的ApplicationContextAwareProcessor;

Web应用中装配ServletContext的ServletContextAwareProcessor;

类加载时编织AspectJ切面的LoadTimeWeaver被LoadTimeWeaverAwareProcessor装配;

关于加载时编织参考Spring官方文档AspectJ官方文档

另外还有几个基于AOP实现的BeanPostProceesor,最常用的就是@Async注解实现异步方法,而这个就是AsyncAnnotationBeanPostProcessor处理器实现的。

关于Spring异步方法的使用可以参考这篇教程

5.6、BeanPostProcessor的子接口

BeanPostProcessor

BeanPostProcessor有三个字接口:

1、InstantiationAwareBeanPostProcessor:添加了实例化对象的回调方法,以及属性值被自动装配时的回调;

2、DestructionAwareBeanPostProcessor:添加了销毁对象前的回调方法;

3、MergedBeanDefinitionPostProcessor:合并BeanDefinition后调用;

既然InstantiationAwareBeanPostProcessor是实例化和属性自动装配的回调,让我们看一下这块代码:

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
///...
// Spring创建Bean对象的整个过程
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

RootBeanDefinition mbdToUse = mbd;

/// 解析并加载BeanDefinition中定义的Class
/// ... 代码省略

/// ...省略异常处理代码
// 第一步:
// 调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
// Processor的方法可能返回一个代理对象,
// 比如Spring AOP的自动代理(@EnableAspectJAutoProxy)。
// 这种情况比较少,可以不考虑
return bean;
}

/// ...省略异常处理代码
/// 根据BeanDefinition创建对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}

/// 调用内部的创建方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {

// 第二步: 实例化Bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

// 调用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
// 让Processor对BeanDefinition最后再进行一些处理
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
/// ...省略异常处理代码
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}

// 将Bean对象缓存起来以解决循环引用的问题
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

Object exposedObject = bean;
/// ...省略异常处理代码
// 填充Bean的属性
populateBean(beanName, mbd, instanceWrapper);
// 初始化Bean对象
exposedObject = initializeBean(beanName, exposedObject, mbd);

///...

/// ...省略异常处理代码
// 注册Disposable接口和DestructionAwareBeanPostProcessor的DisposableBeanAdapter
registerDisposableBeanIfNecessary(beanName, bean, mbd);

return exposedObject;
}

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
///...

// 调用InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation方法
boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}

if (!continueWithPropertyPopulation) {
return;
}

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

// 自动装配对象
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// 根据名称自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}

// 根据类型自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}

pvs = newPvs;
}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
/// 调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}

if (pvs != null) {
// 将依赖的Bean对象注入到新创建的Bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
///...
}

至此,创建Bean的整个过程可以总结为下图:

CreateBean

6. 功能更强大的容器——ApplicationContext

ApplicationContext继承图

ApplicationContext在BeanFactory容器的基础上继承了另外四个接口:

  1. EnvironmentCapable接口:暴露了应用当前的环境配置信息的Environment接口。Environment提供了profilesproperties两方面的配置信息:

    profiles指的是一组Bean的集合,这些Bean可以在xml中配置profile或着使用@Profile注解。Environment对于Profile来说,就是用于决定当前哪个profile被激活了,那个profile应该默认被激活。

    Spring Profile的相关内容可以参考这篇教程

    properties在应用中扮演着重要角色,主要来源形式有:properties文件、JVM系统参数、系统环境变量、JDNI、Servlet容器参数等。

  2. MessageSource接口:提供了消息的参数化与国际化,避免了开发人员编写大量额外的代码处理各种复杂的情况。

    在SpringBoot中使用MessageSource处理校验报错信息,可以参考这篇教程

  3. ApplicationEventPublisher接口:为Spring容器提供了事件发布功能。ApplicationContext容器通过代理ApplicationEventMulticaster实现事件发布功能(具体可以参看AbstractApplicationContext的相关代码)。Spring容器本身也会发布各种事件,如ContextRefreshedEvent,ContextStartedEvent,RequestHandledEvent等。

    Spring Events的相关内容可以参考官方教程这篇教程,Spring容器内置事件可参考这篇教程

  4. ResourcePatternResolver接口:提供了解析资源路径的功能。如/WEB-INF/*-context.xmlclasspath*:context.xml这样的路径。

其次就是中间过渡的ConfigurableApplicationContext接口:

ConfigurableApplicationContext在ApplicationContext的基础上提供了一些配置接口,和ConfigurableBeanFactory类似,ConfigurableApplicationContext将配置和生命周期方法封装在此主要是为了避免对客户端代码可见,ConfigurableApplicationContext接口的方法应该只在应用启动和关闭的时候调用。这里面有这么几个方法比较重要:

1
2
3
4
5
// 启动容器加载配置并实例化所有的单例Bean
// 所有ApplicationContext容器必须refresh()了才能使用
void refresh();
// 关闭容器释放所有相关资源,包括销毁所有缓存的单例Bean
void close();

6.1、AbstractApplicationContext

先让我们看一下refresh()方法。

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
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备ApplicationContext以进行refresh
prepareRefresh();

// 通知子类去刷新内部的BeanFactory
// AbstractApplicationContext提供了三个抽象方法由子类去实现:
// void refreshBeanFactory()
// void closeBeanFactory()
// ConfigurableListableBeanFactory getBeanFactory()
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 对这个BeanFactory进行配置
prepareBeanFactory(beanFactory);

try {
// 让子类再对BeanFactory进行相应的配置
postProcessBeanFactory(beanFactory);

// 调用BeanFactoryPostProcessor
// 并找到beanFactory容器中实现了BeanFactoryPostProcessor接口的bean,一起调用
// 主要这个这个接口和BeanPostProcessor有所区别
invokeBeanFactoryPostProcessors(beanFactory);

// 找出beanFactory中实现了BeanPostProcessor的Bean
// 并将它们以BeanPostProcessor的角色注册到beanFactory中
registerBeanPostProcessors(beanFactory);

// 初始化用于i18n的MessageSource
initMessageSource();

// 初始化用于事件分发的ApplicationEventMulticaster
initApplicationEventMulticaster();

// 让子类做一些其他的初始化,比如web应用中要初始化ThemeSource
onRefresh();

// 找到容器中所有的ApplicationListener并将其注册到ApplicationEventMulticaster中
registerListeners();

// 对BeanFactory进行最后的初始化,然后冻结配置,预初始化所有的单例对象
finishBeanFactoryInitialization(beanFactory);

// 最后一步:完成最后的刷新工作并发布ContextRefreshedEvent事件
finishRefresh();
}

///...
}
}

AbstractApplicationContext提供了很多模版方法给子类去实现,接下来我们看一下最主要的两个子类。

6.2、GenericApplicationContext与AbstractRefreshableApplicationContext

Spring容器的两个体系

GenericApplicationContextRefreshableApplicationContext两个体系内的容器实现本质上都是代理了DefaultListableBeanFactory提供的功能。

两者的区别在于GenericApplicationContext只能refresh()一次,而RefreshableApplicationContext允许refresh()多次。

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
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

private final DefaultListableBeanFactory beanFactory;

/// ...
public GenericApplicationContext() {
// 在构造的时候就创建了beanFactory
// 之后的refresh()等操作都是对这个beanFactory进行操作
this.beanFactory = new DefaultListableBeanFactory();
}
///...
}

public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
///...

@Nullable
private DefaultListableBeanFactory beanFactory;

public AbstractRefreshableApplicationContext() {
}

// 实现AbstractApplicationContext提供的模版方法
// 每次refresh()都会重新创建新的BeanFactory
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
// 销毁已有的容器
destroyBeans();
closeBeanFactory();
}
try {
// 创建新的容器
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(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);
}
}

protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
///...
}

6.3、BeanFactoryPostProcessor

不要将BeanFactoryPostProcessor和前面的BeanPostProcessor搞混,这个接口是BeanFactory初始化后的回调接口。

BeanFactoryPostProcessor可以与BeanDefinition进行交互并进行修改,但不能与Bean实例交互。这样做可能会导致bean过早实例化,从而违反了容器规则并造成了意外的副作用。如果需要与bean实例交互,请考虑实现BeanPostProcessor

常见的BeanFactoryPostProcessor有CustomScopeConfigurer(自定义Scope)、CustomAutowireConfigurer(自定义@Qualifier)、CustomEditorConfigurer(自定义PropertyEditor)。它们都是用来扩展BeanFactory功能的。还有一个EventListenerMethodProcessor是用来处理@EventListener注解的。

BeanFactoryPostProcessor另一个核心的实现类就是ConfigurationClassPostProcessor,它是用来解析@Configuration注解类的处理器。

BeanFactoryPostProcessor

前面提到过Spring3.0开始支持@Configuration的配置,而它是由AnnotationConfigApplicationContext透出的,所以我们从这个类开发分析。

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
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

private final AnnotatedBeanDefinitionReader reader;

private final ClassPathBeanDefinitionScanner scanner;

public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
///...

@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}

@Override
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.scanner.scan(basePackages);
}

///...
}

这里的AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner都是为了解析@Component注解并注册BeanDefinition。

当然这里的@Component还包括@Repository、@Service、@Controller、@Configuration这几个复合注解。

Annotate和Class在读取和扫描过程中都会去调用AnnotationConfigUtilsregisterAnnotationConfigProcessors方法注册Spring的注解处理器,其中包括:

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
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {

DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);

// 注册@Configuration、@Bean、@Import、@ComponentScan等注解的ConfigurationClassPostProcessor
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// 注册@Autowired、@Value等注解的AutowiredAnnotationBeanPostProcessor
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// 注册处理@Required注解的RequiredAnnotationBeanPostProcessor
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// 检查是否有JSR-250的依赖
// 有则注册处理@PostConstruct、@PreDestroy、@Resource等注解的
// CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// 检查JPA的依赖, 有则注册处理@PersistenceUnit、@PersistenceContext注解的
// PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// 注册处理@EventListener注解的EventListenerMethodProcessor
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// 为@EventListener注解的方法提供一个事件类型适配器
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}

return beanDefs;
}

这里我们主要关注ConfigurationClassPostProcessor,因为它实现了BeanDefinitionRegistryPostProcessor接口,所以它会回调两次:

1、先回调BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法,由ConfigurationClassParser解析出所有的ConfigurationClass,再由ConfigurationClassBeanDefinitionReader将所有的ConfigurationClass读取并将BeanDefinition注册到容器中。

2、然后回调BeanFactoryPostProcessor.postProcessBeanFactory方法,其中ConfigurationClassEnhancer使用Cglib对@Configuration类进行动态代理增强,主要是为了调用@Bean注解方法时由BeanFactory负责创建对象并将其放入容器中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public class DemoConfiguration {

@Bean
public ObjectA a(){
return new ObjectA();
}

@Bean
public ObjectB b(){
// 正因为ConfigurationClassEnhancer
// 所以调用a()方法时会从BeanFactory中取出bean,而不是每次创建一个新对象
return new ObjectB(a());
}
}

对于ConfigurationClassPostProcessor更详细的源码分析请参考这两篇文章:

ConfigurationClassPostProcessor源码分析

Spring Boot源码分析

其中比较重要的是@Import注解的处理,因为Spring中很多@EnableXxx注解都是基于这个实现的。

@Import注解内可以填三种类型:

1、@Configuration注解类,2、ImportSelector接口实现类,3、ImportBeanDefinitionRegistrar接口实现类

@EnableXxx => @Import(XxxConfiguration ==> @Configuration) => XxxBeanPostProcessor

​ eg. @EnableScheduling

​ => @Import(XxxSelector ==> ImportSelector)

​ eg. @EnableAsync、@EnableDubboConfig

​ => @Import(XxxRegistrar ==> ImportBeanDefinitionRegistrar)

​ eg. @EnableAspectJAutoProxy、@EnableJpaAuditing、@EnableJpaRepositories

看一下这块的代码:

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
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) throws IOException {

if (importCandidates.isEmpty()) {
return;
}

if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
// 处理ImportSelector实现类
if (candidate.isAssignable(ImportSelector.class)) {
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
// 如果实现的是DeferredImportSelector接口则延迟处理
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
// 直接拿到import的类,递归处理一下
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
// 处理ImportBeanDefinitionRegistrar实现类
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
// 注解将ImportBeanDefinitionRegistrar放到configClass中
// 最后由ConfigurationClassBeanDefinitionReader处理
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// 否则当作@Configuration注解的类处理
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}

至此已将Spring IOC的大部分核心内容的整体结构理清楚了,更多细节上的知识还需要查看源码去理解。

参考资料:

https://www.baeldung.com/spring-factorybean

https://www.baeldung.com/spring-profiles

https://spring.io/blog/2007/06/05/more-on-java-configuration

https://spring.io/blog/2014/11/04/a-quality-qualifier

https://spring.io/blog/2011/08/09/what-s-a-factorybean

https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2

https://spring.io/blog/2010/01/05/task-scheduling-simplifications-in-spring-3-0

https://spring.io/blog/2011/02/17/spring-3-1-m1-introducing-featurespecification-support

https://spring.io/blog/2016/03/04/core-container-refinements-in-spring-framework-4-3