Spring-IOC原理(二)

前言

在上一篇博文《Spring-IOC原理(一)》中已经基本上了解了一下Spring IOC的大致运行流程。也知道了这个流程都是从AnnotationConfigApplicationContext构造方法中发起的,那么本篇博文就从AnnotationConfigApplicationContext构造方法中详细探究一下Spring IOC详细的加载过程;回顾一下AnnotationConfigApplicationContext构造方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
/** 这里会实例化BeanDefinitionReader和BeanDefinitionScanner,并注册一些框架初始化必要的Bean
* 调用无参构造函数,会先调用父类GenericApplicationContext的构造函数,父类构造函数中就是初始化
* DefaultListableBeanFactory,并且赋值给beanFactory。
* 在本类的构造函数中,初始化了一个读取器reader = new AnnotatedBeanDefinitionReader(this);
* 和一个扫描器scanner = new ClassPathBeanDefinitionScanner(this);
* 扫描器scanner的用出不是很大,它仅仅是我们外部手动调用.scan()方法时才会用到的,常规方式是不会用到scanner
*/
this();
/** 注册Bean
* 把传入的类进行注册,这里会有两种方式,一种是传入配置类,一种是传入bean。
* 这里spring会把传统的带有@Configuration注解的类称之为FULL配置类,不带@Configuration注解但是带有@Component
* @Import@ImportResource@Server@ComponentScan 等注解的类称之为Lite配置类
* 我们这里先把带有@Configuration注解的称之为传统配置类,不带该注解的称之为普通类
*/
register(componentClasses);
/** 刷新 */
refresh();
}

一、this()方法详解

在以上的构造方法中,首先是调用的本类的无参构造方法this()ctrl+鼠标左键点进入看看这个构造方法里都干了什么。

1
2
3
4
5
6
7
public AnnotationConfigApplicationContext() {
/** 这里会隐式调用父类构造函数,来初始化DefaultListableBeanFactory */
/** 1、 用来读取Bean配置信息,该配置信息是使用注解配置的 */
this.reader = new AnnotatedBeanDefinitionReader(this);
/** 用来扫描 1中读取到的Bean,这里会扫描配置有@AutoWired@Value等注解*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}

AnnotationConfigApplicationContext无参构造方法中创建了this.reader是一个AnnotatedBeanDefinitionReader类型和this.scanner是一个ClassPathBeanDefinitionScanner类型。

this.reader 注解bean定义读取器,主要作用是读取被注解标记的bean

this.scanner 扫描器,如果使用注解的方式不会使用到这个扫描器;只有在外部通过.scan(...)方法时才会调到,常规方法时不会用到的。

因为这里主要是用的注解的方式进行调试的,所以this.scanner也不会使用到,这里也就不去研究。接下来只研究this.reader

因为AnnotationConfigApplicationContext类是继承了父类GenericApplicationContext的。如下类关系图

AnnotationConfigApplicationContext类关系图

所以在AnnotationConfigApplicationContext构造方法执行之前,首先会执行GenericApplicationContetxt类的默认构造方法,来看看GenericApplicationContetxt的构造方法里干了什么。

1
2
3
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}

这里创建了一个bean工厂,该bean工厂在后面进行bean初始化的时候会用到;其实这个beanFactory就是我们所说的容器

等到GenericApplicationContext()执行完毕之后,接下来才会执行我们的AnnotationConfigApplicationContext()构造方法中的

1
2
/** 1、 用来读取Bean配置信息,该配置信息是使用注解配置的 */
this.reader = new AnnotatedBeanDefinitionReader(this);

继续点进入,发现有调了AnnotatedBeanDefinitionReader的构造方法。继续跟进,what!!! 怎么还停留在构造方法中,嵌套这么复杂……想一想这不是设计模式中的门面方法么。看到了代码

1
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

二、registerAnnotationConfigProcessors方法详解

这回该是开始正式干活的方法了,点进去。

1
2
3
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}

。。。。此时一万只草泥马从眼前奔腾而过!!!既然已经到这里了,那我就在赌一把,继续点进入调用的方法中。

豁然开朗,终于看到了干活的方法了。好家伙小100行的方法,全是if判断。大致看一下代码

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
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable 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<>(8);
/**
* 将ConfigurationClassPostProcessor分装成RootBeanDefinition注册到容器中
*/
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));
}
/**
* 注册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));
}
/**
* 注册CommonAnnotationBeanPostProcessor
*/
// Check for JSR-250 support, and if present add the 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));
}
/**
* 注册PersistenceAnnotationBeanPostProcessor
*/
// Check for JPA support, and if present add the 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));
}
/**
* 注册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));
}
/**
* 注册DefaultEventListenerFactory
*/
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;
}

从上述代码中可以看出在registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) 方法中主要将spring初始化要用到的后置处理器封装成了RootBeanDefinition并且将他们注册到set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8)中。主要包括

  • ConfigurationClassPostProcessor:这个后置处理器后期会解析带有@Configuration@Import@Component@ComponentScan等注解,在spring中给常重要
  • AutoWiredAnnotationBeanPostProcessor:主要用来解析带有@AutoWired注解的属性,用来注入属性实例
  • CommonAnnotationBeanPostProcessor:用来解析通用注解,比如@Resource@WebServiceRef@EJB注解。这三个注解都是定义在javax.*包下,属于java中的注解
  • PersistenceAnnotationBeanPostProcessor:用来解析@PersistenceUnit@PersistenceContext注解
  • EventListenerMethodProcessor:用来解析@EventListener注解,
  • DefaultEventListenerFactory:处理默认监听事件,当没有在程序中指定事件

三、registerPostProcessor方法详解

接下来继续看一下registerPostProcessor(registry,def,beanName),点进入这个方法看看内部有什么实现。

1
2
3
4
5
6
7
8
9
10
11
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

// 标记bean角色是spring内部定义,并非用户定义
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
/**
* 注册bean定义,registry的实现类是DefaultListableBeanFactory
*/
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}

该方法中主要设置了bean的角色和注册bean定义,

四、registerBeanDefinition方法详解

继续进入registry.registerBeanDefinition(beanName, definition);中,注意registerBeanDefinition()是接口中的方法,该方法中的实现是在接口实现类中,而registry的实现类是DefaultListableBeanFactory,所以最终我们要进入到DefaultListableBeanFactory类中的registerBeanDefinition(beanName,definition)方法中。

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
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {

Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");

if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}

/** 先从beanDefinitionMap一级缓存中获取bean */
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
/** 如果一级缓存中有bean */
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
/** 将bean设置到一级缓存 */
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
/**
* beanDefinitionMap是Map<String,BeanDefinition>,这里把beanName作为key,beanDefinition作为value
*/
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}

if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}

整个方法中主要是将registerAnnotationConfigProcessors(BeanDefinitionRegistry)方法中注册的一些Bean后置处理器做了处理,将这些后置处理器注册成BeanDefinition对象并且将其放入Map<String,BeanDefinition>类型的beanDefinitionMap中。

大概流程是:首先根据给定的beanNamebeanDefinitionMap中拿bean定义,如果bean定义不为空。继续判断是否允许重复创建bean定义(如果允许重复创建bean定义,并且给定的bean定义名称已经在beanDefinitionMap中已经存在实例,则第二次创建的bean定义实例会覆盖第一次bean定义实例。可以通过spring.main.allow-bean-definition-overriding来指定是否允许覆盖);如果不允许重复创建bean定义即allowBeanDefinitionOverriding=false,会抛出BeanDefinitionOverrideException异常;如果允许重复创建bean定义即allowReanDefinitionOverriding=true;继续判断bean定义角色、bean定义类型,如果都通过,则将传入的bean定义实例放入beanDefinitionMap中;key为beanName,value为BeanDefinition实例对象;

如果从beanDefinitionMap中拿出的bean定义为空,即第一次进来,将传进来的bean定义放入beanDefinitionMap中,同时将beanName放入beanDefinitionNames中。然后判断从beanDefinitionMap拿出来的bean定义 不为空 或者 已经有实例的单例bean,则递归调用resetBeanDefinition()

上面分析中说了,bean最后会保存在beanDefinitionMap中,beanName会保存在beanDefinitionNames中;beanDefinitionMap是一个Map,key是beanName,value是BeanDefinitionbeanDefinitionNames是字符串列表。从这里我们可以看出DefaultListableBeanFactory就是我们常说的容器了。可以在这方法中打一个端点调试一下。

端点调试

DefaultListableBeanFactory中的beanDefinitionMapbeanDefinitionNames是很重要的,后面会经常看到他们的身影。

这里只是简单的把创建bean所需要的基本信息放入到了工厂中,还没有进行真正的生产bean。上面我们提到注册了好多bean后置处理器,其中有一个很重要的bean是ConfigurationClassPostProcessor ,这个bean实现了一个接口BeanDefinitionRegistryPostProcessor接口,BeanDefinitionRegistryPostProcessor接口又继承了BeanFactoryPostProcessor接口;而BeanFactoryPostProcessor是Spring的扩展点之一,必须记住ConfigurationClassPostProcessor类的继承关系。

ConfigurationClassPostProcessor

除了注册ConfigurationClassPostProcessor,还注册了AutoWiredAnnotationBeanPostProcessor bean,该bean实现了一个接口MergedBeanDefinitionPostProcessor,而MergedBeanDefinitionPostProcessor接口继承了BeanPostProcessor。**BeanPostProcessor也是Spring的一个扩展点之一,也是非常重要,需要记住。**

AutoWiredAnnotationBeanPostProcessor类关系图

到此,this()方法中的流程分析完毕。

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

请我喝杯咖啡吧~

支付宝
微信