深入源码级别看spring bean创建过程

我们通常聊到spring bean的生命周期,大多是从网上找帖子背些基本概念,这样我们学到的东西是不够直观清晰的,这篇文章我就试着从源码级别来讲清楚bean的创建过程。

一、准备demo代码

我们既然要深入源码来看bean的创建过程,那么就要写一个简单的demo,用于我们debug跟踪代码的执行过程,从而可以非常直观的看到核心源码发挥的作用。

java 复制代码
package com.example.bean;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test1 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        Student student1 = (Student)context.getBean("student");
        Student student2 = (Student)context.getBean("student");
        System.out.println(student1 == student2);
    }
}

可以看到里面涉及到了Student类,Student类代码如下:

java 复制代码
package com.example.bean;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Student implements InitializingBean {

    @Autowired
    private Cource cource;

    private String name;

    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.name = "zhangsan";
        this.age = 10;
    }
}

在学生类中还注入了课程类Cource,这个类代码如下:

java 复制代码
package com.example.bean;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class Cource implements InitializingBean {

    private String courceName;

    public String getCourceName() {
        return courceName;
    }

    public void setCourceName(String courceName) {
        this.courceName = courceName;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.courceName = "语文";
    }
}

除了这两个我们要重点关注的类之外,我们还要关注AppConfig类,这个类用于指定我们扫描包的范围,是非常重要的。

java 复制代码
package com.example.bean;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.example.bean")
public class AppConfig {
}

我们整体代码的结构如下图所示。

上面在Test1这个类中我们使用的AnnotationConfigApplicationContext 是 Spring 框架中用于基于注解配置的应用程序上下文实现类。如果你程序还是用xml来定义bean的话,就得用ClassPathXmlApplicationContext这个上下文实现类了。

二、准备注解解析器和组件扫描器

我们看代码new AnnotationConfigApplicationContext(AppConfig.class);点击进去看里面的源码,如下所示。

可以看到入参是不固定数量的,不过从形参名称componentClasses就可以看出来入参跟Component相关,而我们的入参类AppConfig类上就有@ComponentScan注解,这个注解用于扫描指定包下的类。

java 复制代码
	/**
	 * Create a new AnnotationConfigApplicationContext, deriving bean definitions
	 * from the given component classes and automatically refreshing the context.
	 * @param componentClasses one or more component classes — for example,
	 * {@link Configuration @Configuration} classes
	 */
	public AnnotationConfigApplicationContext(Class <? > ...componentClasses) {
	    this();
	    register(componentClasses);
	    refresh();
	}

接下来我们看构造方法的第一行代码this();显然这是调用了内部的无参构造器,我们看看这个无参构造器中都有哪些代码,如下所示。

复制代码
   其中StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");这行代码只是启动一个性能监控步骤,用于记录创建AnnotatedBeanDefinitionReader的耗时,它不是重点,这个我们直接忽略它。

2.1 注解解析器

接下来就是this.reader = new AnnotatedBeanDefinitionReader(this);这是准备注解解析器的代码,我们点进去看看里面的逻辑。

java 复制代码
/**
 * Create a new AnnotationConfigApplicationContext that needs to be populated
 * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
 */
public AnnotationConfigApplicationContext() {
    StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
    this.reader = new AnnotatedBeanDefinitionReader(this);
    createAnnotatedBeanDefReader.end();
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

可以看到如下图所示内容,可以看到我们把AnnotationConfigApplicationContext作为BeanDefinitionRegistry类型的入参传进来了,然后内部调用到registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)方法的调用链如下图所示,这些代码不是重点,我们知道是这么个调用流程即可。

之所以把AnnotationConfigApplicationContext作为参数可以直接作为AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry)的参数传过来是因为AnnotationConfigApplicationContext是BeanDefinitionRegistry的实现类,如下图所示。

我们接着回到上面提到的registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)方法,如下所示,我们关注里面的registerAnnotationConfigProcessors(registry, null);方法。

java 复制代码
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
	registerAnnotationConfigProcessors(registry, null);
}

方法源码如下,这里面上来就看到一个非常核心的组件DefaultListableBeanFactory,这个组件有多核心,我们总结一下这个组件的功能就知道了。

java 复制代码
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());
        }
    }

   //......这里暂时省略一部分代码
}

DefaultListableBeanFactory说明如下:

DefaultListableBeanFactory是spring框架中最核心的BeanFactory实现类,负责管理bean的定义、实例化、依赖注入以及生命周期,它是Spring IoC容器的基础设施,同时也是高级容器(如ApplicationContext)的底层实现。好家伙,这一个组件就包括了这么多功能,下面具体说下每个功能。

1)Bean定义管理

实现了BeanDefinitionRegistry接口,支持动态注册和存储Bean定义(BeanDefinition)。

另一个就是维护了一个Map<String, BeanDefinition>结构的beanDefinitionMap,这个map用来存储所有bean的基础信息(BeanDefinition在创建bean时使用)。

2)Bean实例化与依赖注入

继承AbstractAutowireCapableBeanFactory,提供bean的实例化、属性填充(populateBean)和初始化(initializeBean)逻辑。

支持构造器注入和Setter注入。

3)单例与作用域管理

维护单例bean缓存(singletonObjects),支持singleton和prototype作用域。

通过三级缓存(第三级singletonFactories、第二级earlySingletonObjects、第一级singletonObjects)解决循环依赖问题。

4)类型转换与自动装配

实现AutowireCapableBeanFactory,支持按类型(byType)或名称(byName)自动装配。

处理@Autowired、@Value、@Resource等注解的依赖注入。

5)生命周期回调

处理InitializingBean、DisposableBean 等接口的回调。

支持@PostConstruct 和@PreDestroy 注解。

6)Bean后置处理

通过BeanPostProcessor和BeanFactoryPostProcessor扩展bean的创建和初始化逻辑。

说完DefaultListableBeanFactory,我们再回到刚才registerAnnotationConfigProcessors方法的源码,如下所示。我们第一步获取到DefaultListableBeanFactory之后,便接着给这个beanFactory设置dependencyComparator和autowireCandidateResolver这两个组件。

java 复制代码
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());
        }
    }

    //......这里暂时省略一部分代码
}

其中beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);这句代码是要配置依赖比较器,确保BeanFactory使用AnnotationAwareOrderComparator作为依赖比较器,它的作用是在自动装配时,spring需要确定多个候选bean的注入顺序,这时AnnotationAwareOrderComparator可以解析@Order或者@Priority注解以及Ordered接口按优先级排序bean。

其次就是beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());这句代码是配置自动装配候选解析器。它的作用是在自动装配过程中决定哪些bean符合条件作为候选依赖。注解支持@Qualifier(按名称精确匹配 Bean)、@Value(解析 SpEL 表达式或占位符)、@Lazy(延迟初始化代理)。

接下来我们继续分析registerAnnotationConfigProcessors方法的源码如下所示,可以看到是要组装beanDefs,这是个由BeanDefinitionHolder组成的Set集合。然后看到下面很多if判断并且往这个beanDefs里面添加元素,我们就拿第一个if判断来举例。

java 复制代码
public static Set < BeanDefinitionHolder > registerAnnotationConfigProcessors(
    BeanDefinitionRegistry registry, @Nullable Object source) {

    //......这里暂时省略一部分代码

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

    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));
    }

    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));
    }

    // 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));
    }

    // 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));
    }

    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));
    }

    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;
}

第一个If判断如下,上来先判断在注册器registry中是否有常量CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME,这个常量我们在当前AnnotationConfigUtils这个类中可以看到如下图所示,是一个挺长名字的字符串。

java 复制代码
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));
}

我们看registry.containsBeanDefinition方法内部逻辑,可以看到有三个实现类,我们刚从上面知道我们使用工厂是DefaultListableBeanFactory,因此我们进入到DefaultListableBeanFactory这个内部看看

方法registry.containsBeanDefinition具体代码如下,可以看到就是判断beanDefinitionMap中是否存在当前key。由于我们目前还处于最开始阶段,因此这里beanDefinitionMap是空,也就是key在map中不存在。

java 复制代码
@Override
public boolean containsBeanDefinition(String beanName) {
	Assert.notNull(beanName, "Bean name must not be null");
	return this.beanDefinitionMap.containsKey(beanName);
}

beanDefinitionMap的定义如下。

java 复制代码
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

因此就进入到if内部,如下所示,可以看到定义了一个根beanDefinition,也就是RootBeanDefinition,它是由ConfigurationClassPostProcessor真正来实现具体功能的。ConfigurationClassPostProcessor是spring实现注解驱动编程(如@Configuration、@Bean、@ComponentScan等)的关键组件。负责解析和处理基于注解的配置元数据。

java 复制代码
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));
}

然后我们进入到beanDefs.add()方法中调用的方法registerPostProcessor,看看里面做了什么操作。这里面我们重点关注registry.registerBeanDefinition(beanName, definition);这行代码

java 复制代码
private static BeanDefinitionHolder registerPostProcessor(
	BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

	definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	registry.registerBeanDefinition(beanName, definition);
	return new BeanDefinitionHolder(definition, beanName);
}

DefaultListableBeanFactory工厂类中registerBeanDefinition方法源码如下所示,我们目前beanDefinitionMap中还没有元素,因此existingDefinition是null,因此走else分支代码,else分支代码中上来是判断目前是不是正在创建bean,代码:if (hasBeanCreationStarted())

java 复制代码
@Override
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);
        }
    }

    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    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 + "]");
            }
        }
        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
            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();
    }
}

hasBeanCreationStarted方法内部代码如下,其实就是判断了一个名叫alreadyCreated的集合是否有元素,在这个阶段这个集合还没有开始创建bean,这里集合是空的,因此返回的是false。

java 复制代码
/**
 * Check whether this factory's bean creation phase already started,
 * i.e. whether any bean has been marked as created in the meantime.
 * @since 4.2.2
 * @see #markBeanAsCreated
 */
protected boolean hasBeanCreationStarted() {
    return !this.alreadyCreated.isEmpty();
}

回过来上面的registerBeanDefinition方法代码就会走到如下图所示位置,这里就是将beanName作为key,将beanDefinition作为value保存到了beanDefinitionMap当中,并且把beanName也专门保存到beanDefinitionNames集合当中。

我们再回到上面提到的registerAnnotationConfigProcessors方法,我们刚才只是举例说明了第一个if条件判断中的逻辑。另外还要简单提一下的是beanName为下面二个

java 复制代码
	/**
	 * The bean name of the internally managed Autowired annotation processor.
	 */
	public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
			"org.springframework.context.annotation.internalAutowiredAnnotationProcessor";

	/**
	 * The bean name of the internally managed JSR-250 annotation processor.
	 */
	public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
			"org.springframework.context.annotation.internalCommonAnnotationProcessor";

其中org.springframework.context.annotation.internalAutowiredAnnotationProcessor这个beanName对应的根beanDefinition是AutowiredAnnotationBeanPostProcessor,它是spring依赖注入机制的关键组件,负责处理@Autowired、@Value、@Inject等注解,完成bean的自动装配逻辑。

另外org.springframework.context.annotation.internalCommonAnnotationProcessor这个beanName对应的根beanDefinition是CommonAnnotationBeanPostProcessor,它是BeanPostProcessor的实现类,主要功能包括:

1)处理生命周期注解

@PostConstruct:在bean初始化阶段,(afterPropertiesSet 之后、init-method 之前)调用标记的方法。

@PreDestroy:在bean销毁阶段调用标记的方法。

2)处理依赖注入注解

@Resource:按名称或类型注入依赖,支持JNDI查找(需配置)。

2.2 组件扫描器

我们再回到AnnotationConfigApplicationContext无参构造器源码这块,我们下面接着分析this.scanner = new ClassPathBeanDefinitionScanner(this);这行代码

java 复制代码
public AnnotationConfigApplicationContext() {
	StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
	this.reader = new AnnotatedBeanDefinitionReader(this);
	createAnnotatedBeanDefReader.end();
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

嵌套比较深,调用链如下,我们重点关注下面setResourceLoader(resourceLoader);方法。

方法setResourceLoader内容源码如下,该方法用于配置与资源加载相关的核心组件,支持类路径扫描和组件索引加载,常用于spring的组件扫描器(如ClassPathBeanDefinitionScanner)或元数据处理类中。

java 复制代码
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
	this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
	this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
	this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());
}

1)初始化资源模式解析器

this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);是将ResourceLoader转换为ResourcePatternResolver,目的是支持从类路径中按模式(如classpath*:com/example/**/*.class)批量加载资源。

2)初始化元数据读取工厂

this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);

CachingMetadataReaderFactory基于ResourceLoader创建可缓存的MetadataReaderFactory,它的功能是读取.class文件的元数据(如类名、注解、接口等),避免重复解析开销。并且默认使用ConcurrentHashMap缓存MetadataReader,value为资源描述符。

3. 加载组件索引

this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());从类路径的 META-INF/spring.components 文件中加载组件索引,避免全路径扫描,显著提升大型应用的启动速度。不过这个需要依赖maven

java 复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-indexer</artifactId>
    <optional>true</optional>
</dependency>

三、将指定配置类存放到注解解析器

我们回到AnnotationConfigApplicationContext的构造方法这里,看第二行register(commponentClasses)代码。

java 复制代码
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
	this();
	register(componentClasses);
	refresh();
}

register内部源码如下,可以看到我们又看到了熟悉的reader变量,这个我们在上面讲到的注解解析器的时候讲到了,里面存放的是beanName和对应的根beanDefinition,现在这里我们要把我们制定的AppConfig这个配置类也存放到reader当中。

java 复制代码
@Override
public void register(Class <? > ...componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
        .tag("classes", () - > Arrays.toString(componentClasses));
    this.reader.register(componentClasses);
    registerComponentClass.end();
}

调用层级较深,调用链如下图所示

doRegisterBean方法内部源码如下,可以看到生成了一个AnnotatedGenericBeanDefinition实例对象,它是Spring Framework 中用于封装基于注解的Bean定义的核心类。它继承自GenericBeanDefinition,并扩展了对注解元数据的支持,主要用于处理通过注解驱动配置(如@Configuration、@Component等)定义的bean。最典型的就是处理像我们AppConfig这样带有@Configuration注解的配置类,创建AnnotatedGenericBeanDefinition并存储该类的元数据。

java 复制代码
private < T > void doRegisterBean(Class < T > beanClass, @Nullable String name, @Nullable Class <? extends Annotation > [] qualifiers, @Nullable Supplier < T > supplier, @Nullable BeanDefinitionCustomizer[] customizers) {

    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }

    abd.setInstanceSupplier(supplier);
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    if (qualifiers != null) {
        for (Class <? extends Annotation > qualifier: qualifiers) {
            if (Primary.class == qualifier) {
                abd.setPrimary(true);
            } else if (Lazy.class == qualifier) {
                abd.setLazyInit(true);
            } else {
                abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }
    if (customizers != null) {
        for (BeanDefinitionCustomizer customizer: customizers) {
            customizer.customize(abd);
        }
    }

    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

四、执行BeanFactoryPostProcessors

我们接下来分析的就是spring中最核心的方法refresh方法中的内容了,我们跳过前面不重要的步骤,直接看执行BeanFactoryPostProcessors的内容,如下图所示。

我们进入到invokeBeanFactoryPostProcessors方法内部,如下所示,我们重点关注第一行的代码PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

java 复制代码
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

	 // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
	 // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
	 if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
	    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
	    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	 }
}

我们进入到我们方法内部,这个方法代码非常多,我们不用都关注,我们抽出重点需要关注的点关注即可。

java 复制代码
public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}

下面我把重点需要关注的代码粘贴出来,其中下面第一行代码是通过BeanDefinitionRegistryPostProcessor这个类找到我们在上面2.1中注解解析器中提到的对应的beanName,这里对应的beanName是org.springframework.context.annotation.internalConfigurationAnnotationProcessor(我们在2.1中就截图说明了这个beanName对应了ConfigurationClassPostProcessor这个根beanDefinition,而ConfigurationClassPostProcessor又是BeanDefinitionRegistryPostProcessor的实现类)

java 复制代码
String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
	if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
			processedBeans.add(ppName);
	}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());

接下来for循环中就是判断org.springframework.context.annotation.internalConfigurationAnnotationProcessor是否匹配,我们通过2.1节可以知道DefaultListableBeanFactory这个组件是支持优先级的,因此走到if内部,currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));这行代码便是要通过ppName(也就是我们前面提到的beanName)获取对应的beandefinition,我们这里显然应该得到的就是ConfigurationClassPostProcessor

java 复制代码
for (String ppName : postProcessorNames) {
	if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
			processedBeans.add(ppName);
	}
}

然后我们就重点关注invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());这行代码了。这个方法内部代码如下,这里面重点关注的是for循环内部的postProcessor.postProcessBeanDefinitionRegistry(registry);这行代码。

java 复制代码
private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {

	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
					.tag("postProcessor", postProcessor::toString);
		postProcessor.postProcessBeanDefinitionRegistry(registry);
		postProcessBeanDefRegistry.end();
	}
}

postProcessBeanDefinitionRegistry方法源码如下,在这个方法内部我们重点关注最后面那行processConfigBeanDefinitions(registry);

java 复制代码
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	int registryId = System.identityHashCode(registry);
	if (this.registriesPostProcessed.contains(registryId)) {
	        throw new IllegalStateException(
	            "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
	}
	if (this.factoriesPostProcessed.contains(registryId)) {
	        throw new IllegalStateException(
	            "postProcessBeanFactory already called on this post-processor against " + registry);
	}
	this.registriesPostProcessed.add(registryId);

	processConfigBeanDefinitions(registry);
}

processConfigBeanDefinitions方法源码如下,又是有很多代码,我们重点关注的是parser.parse(candidates)方法,如下图所示。

java 复制代码
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
		String[] candidateNames = registry.getBeanDefinitionNames();

		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
			if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// Return immediately if no @Configuration classes were found
		if (configCandidates.isEmpty()) {
			return;
		}

		// Sort by previously determined @Order value, if applicable
		configCandidates.sort((bd1, bd2) -> {
			int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
			int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
			return Integer.compare(i1, i2);
		});

		// Detect any custom bean name generation strategy supplied through the enclosing application context
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet) {
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
						AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
				if (generator != null) {
					this.componentScanBeanNameGenerator = generator;
					this.importBeanNameGenerator = generator;
				}
			}
		}

		if (this.environment == null) {
			this.environment = new StandardEnvironment();
		}

		// Parse each @Configuration class
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
		do {
			StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
			parser.parse(candidates);
			parser.validate();

			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);

			// Read the model and create bean definitions based on its content
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
			this.reader.loadBeanDefinitions(configClasses);
			alreadyParsed.addAll(configClasses);
			processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();

			candidates.clear();
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<>();
				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}
				for (String candidateName : newCandidateNames) {
					if (!oldCandidateNames.contains(candidateName)) {
						BeanDefinition bd = registry.getBeanDefinition(candidateName);
						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
							candidates.add(new BeanDefinitionHolder(bd, candidateName));
						}
					}
				}
				candidateNames = newCandidateNames;
			}
		}
		while (!candidates.isEmpty());

		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
		if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
			sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
		}

		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			// Clear cache in externally provided MetadataReaderFactory; this is a no-op
			// for a shared cache since it'll be cleared by the ApplicationContext.
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}

我们继续看parse方法内的源码,可以看到try中if、else if还有else都调用了本类中一个parse方法名一样,参数不一样的parse方法,这个是我们重点关注的。

java 复制代码
public void parse(Set < BeanDefinitionHolder > configCandidates) {
    for (BeanDefinitionHolder holder: configCandidates) {
        BeanDefinition bd = holder.getBeanDefinition();
        try {
            if (bd instanceof AnnotatedBeanDefinition) {
                parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
            } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
                parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
            } else {
                parse(bd.getBeanClassName(), holder.getBeanName());
            }
        } catch (BeanDefinitionStoreException ex) {
            throw ex;
        } catch (Throwable ex) {
            throw new BeanDefinitionStoreException(
                "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
        }
    }

    this.deferredImportSelectorHandler.process();
}

这个同名prase方法内部代码如下。

java 复制代码
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
	processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}

我们继续到processConfigurationClass方法内部查看源码,如下所示,

java 复制代码
protected void processConfigurationClass(ConfigurationClass configClass, Predicate < String > filter) throws IOException {
    if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
        return;
    }

    ConfigurationClass existingClass = this.configurationClasses.get(configClass);
    if (existingClass != null) {
        if (configClass.isImported()) {
            if (existingClass.isImported()) {
                existingClass.mergeImportedBy(configClass);
            }
            // Otherwise ignore new imported config class; existing non-imported class overrides it.
            return;
        } else {
            // Explicit bean definition found, probably replacing an import.
            // Let's remove the old one and go with the new one.
            this.configurationClasses.remove(configClass);
            this.knownSuperclasses.values().removeIf(configClass::equals);
        }
    }

    // Recursively process the configuration class and its superclass hierarchy.
    SourceClass sourceClass = asSourceClass(configClass, filter);
    do {
        sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
    }
    while (sourceClass != null);

    this.configurationClasses.put(configClass, configClass);
}

我们需要重点关注的代码是如下图所示地方,

其中componentScans运行得到的结果如下图所示,可以看到basePackages下面就是我们的AppConfig配置类中指定要扫描的包路径。

接着看componentScanParser.parse方法的源码,又是一大坨代码,我们直接看最后一行代码return scanner.doScan(StringUtils.toStringArray(basePackages));

java 复制代码
public Set < BeanDefinitionHolder > parse(AnnotationAttributes componentScan, String declaringClass) {
    ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
        componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

    Class <? extends BeanNameGenerator > generatorClass = componentScan.getClass("nameGenerator");
    boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
    scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
        BeanUtils.instantiateClass(generatorClass));

    ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
    if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
        scanner.setScopedProxyMode(scopedProxyMode);
    } else {
        Class <? extends ScopeMetadataResolver > resolverClass = componentScan.getClass("scopeResolver");
        scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
    }

    scanner.setResourcePattern(componentScan.getString("resourcePattern"));

    for (AnnotationAttributes includeFilterAttributes: componentScan.getAnnotationArray("includeFilters")) {
        List < TypeFilter > typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,
            this.resourceLoader, this.registry);
        for (TypeFilter typeFilter: typeFilters) {
            scanner.addIncludeFilter(typeFilter);
        }
    }
    for (AnnotationAttributes excludeFilterAttributes: componentScan.getAnnotationArray("excludeFilters")) {
        List < TypeFilter > typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,
            this.resourceLoader, this.registry);
        for (TypeFilter typeFilter: typeFilters) {
            scanner.addExcludeFilter(typeFilter);
        }
    }

    boolean lazyInit = componentScan.getBoolean("lazyInit");
    if (lazyInit) {
        scanner.getBeanDefinitionDefaults().setLazyInit(true);
    }

    Set < String > basePackages = new LinkedHashSet < > ();
    String[] basePackagesArray = componentScan.getStringArray("basePackages");
    for (String pkg: basePackagesArray) {
        String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
            ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
        Collections.addAll(basePackages, tokenized);
    }
    for (Class <? > clazz: componentScan.getClassArray("basePackageClasses")) {
        basePackages.add(ClassUtils.getPackageName(clazz));
    }
    if (basePackages.isEmpty()) {
        basePackages.add(ClassUtils.getPackageName(declaringClass));
    }

    scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {@
        Override
        protected boolean matchClassName(String className) {
            return declaringClass.equals(className);
        }
    });
    return scanner.doScan(StringUtils.toStringArray(basePackages));
}

doScan内部源码如下,我们重点关注其中的外层for循环中的第一行代码Set<BeanDefinition> candidates = findCandidateComponents(basePackage);

java 复制代码
protected Set < BeanDefinitionHolder > doScan(String...basePackages) {
    Assert.notEmpty(basePackages, "At least one base package must be specified");
    Set < BeanDefinitionHolder > beanDefinitions = new LinkedHashSet < > ();
    for (String basePackage: basePackages) {
        Set < BeanDefinition > candidates = findCandidateComponents(basePackage);
        for (BeanDefinition candidate: candidates) {
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
            candidate.setScope(scopeMetadata.getScopeName());
            String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
            if (candidate instanceof AbstractBeanDefinition) {
                postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
            }
            if (candidate instanceof AnnotatedBeanDefinition) {
                AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
            }
            if (checkCandidate(beanName, candidate)) {
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                definitionHolder =
                    AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                beanDefinitions.add(definitionHolder);
                registerBeanDefinition(definitionHolder, this.registry);
            }
        }
    }
    return beanDefinitions;
}

findCandidateComponents方法源码如下:我们重点关注的是return scanCandidateComponents(basePackage);这行代码。

java 复制代码
public Set < BeanDefinition > findCandidateComponents(String basePackage) {
	if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
	    return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
	 } else {
	    return scanCandidateComponents(basePackage);
	 }
}

scanCandidateComponents方法源码如下所示,其中packageSearchPath获取到的值如下图,很明显就是要把com/example/bean包下的所有类都扫描出来

下面resources这个变量的值刚好可以验证我们的猜想,如下图所示。从而到这里就可以知道我们是在这一步将AppConfig配置类中指定的com/example/bean包下的所有类扫描出来的,并且后面会组装成BeanDefinition存起来,从而给bean的实例化、初始化提供基础条件。

java 复制代码
private Set < BeanDefinition > scanCandidateComponents(String basePackage) {
    Set < BeanDefinition > candidates = new LinkedHashSet < > ();
    try {
        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
            resolveBasePackage(basePackage) + '/' + this.resourcePattern;
        Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
        boolean traceEnabled = logger.isTraceEnabled();
        boolean debugEnabled = logger.isDebugEnabled();
        for (Resource resource: resources) {
            if (traceEnabled) {
                logger.trace("Scanning " + resource);
            }
            try {
                MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
                if (isCandidateComponent(metadataReader)) {
                    ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                    sbd.setSource(resource);
                    if (isCandidateComponent(sbd)) {
                        if (debugEnabled) {
                            logger.debug("Identified candidate component class: " + resource);
                        }
                        candidates.add(sbd);
                    } else {
                        if (debugEnabled) {
                            logger.debug("Ignored because not a concrete top-level class: " + resource);
                        }
                    }
                } else {
                    if (traceEnabled) {
                        logger.trace("Ignored because not matching any filter: " + resource);
                    }
                }
            } catch (FileNotFoundException ex) {
                if (traceEnabled) {
                    logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());
                }
            } catch (Throwable ex) {
                throw new BeanDefinitionStoreException(
                    "Failed to read candidate component class: " + resource, ex);
            }
        }
    } catch (IOException ex) {
        throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
    }
    return candidates;
}

五、实例化

在上面invokeBeanFactoryPostProcessors方法执行完后,我们已经扫描出了com.example.bean目录下所有类并生成了对应的BeanDefinition,用于后面创建实例。下面通过源码来了解一下这块。我们要重点关注的是spring的refresh方法中的finishBeanFactoryInitialization(beanFactory);这行代码。

我们进入finishBeanFactoryInitialization方法内部,代码挺多,我们跳过不重要的,直接看这个方法的最后一行beanFactory.preInstantiateSingletons();内的实现逻辑

java 复制代码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    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 BeanFactoryPostProcessor
    // (such as a PropertySourcesPlaceholderConfigurer 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.
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons();
}

preInstantiateSingletons方法内部代码如下,我们要关注的是for循环中的getBean(beanName)方法。

java 复制代码
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.
    List < String > beanNames = new ArrayList < > (this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName: beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            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 {
                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();
        }
    }
}

getBean(beanName);方法源码如下

java 复制代码
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

然后接着看doGetBean方法的源码,如下,我们重点关注的是if (mbd.isSingleton())这个if判断的内部的return createBean(beanName, mbd, args);这行代码。

java 复制代码
protected < T > T doGetBean(
    String name, @Nullable Class < T > requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {

    String beanName = transformedBeanName(name);
    Object beanInstance;

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                    "' that is not fully initialized yet - a consequence of a circular reference");
            } else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                    nameToLookup, requiredType, args, typeCheckOnly);
            } else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            } else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            } else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
            .tag("beanName", name);
        try {
            if (requiredType != null) {
                beanCreation.tag("beanType", requiredType::toString);
            }
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            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);
                    try {
                        getBean(dep);
                    } catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // Create bean instance.
            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);
            } else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                } finally {
                    afterPrototypeCreation(beanName);
                }
                beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                    throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
                }
                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, () - > {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        } finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException ex) {
                    throw new ScopeNotActiveException(beanName, scopeName, ex);
                }
            }
        } catch (BeansException ex) {
            beanCreation.tag("exception", ex.getClass().toString());
            beanCreation.tag("message", String.valueOf(ex.getMessage()));
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        } finally {
            beanCreation.end();
        }
    }

    return adaptBeanInstance(name, beanInstance, requiredType);
}

然后看createBean方法内部源码如下,这里我们重点关注的是最下面那个try中的Object beanInstance = doCreateBean(beanName, mbdToUse, args);这行代码。

java 复制代码
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

    if (logger.isTraceEnabled()) {
        logger.trace("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;

    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    Class <? > resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        mbdToUse.prepareMethodOverrides();
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    } catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
    }

    try {
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        // A previously detected exception with proper bean creation context already,
        // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
        throw ex;
    } catch (Throwable ex) {
        throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

然后我们进入到doCreateBean内部,我们现在要关注实例化,因此很明显,我们应该重点关注的是if (instanceWrapper == null) 这个if条件内的instanceWrapper = createBeanInstance(beanName, mbd, args);这行代码。

java 复制代码
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        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;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized(mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, () - > getEarlyBeanReference(beanName, mbd, bean));
    }

    // 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);
        }
    }

    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set < String > actualDependentBeans = new LinkedHashSet < > (dependentBeans.length);
                for (String dependentBean: dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                        "Bean with name '" + beanName + "' has been injected into other beans [" +
                        StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                        "] in its raw version as part of a circular reference, but has eventually been " +
                        "wrapped. This means that said other beans do not use the final version of the " +
                        "bean. This is often the result of over-eager type matching - consider using " +
                        "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

然后我们看createBeanInstance方法内部源码,如下,我们重点关注的是最后一行代码return instantiateBean(beanName, mbd);

java 复制代码
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    Class <? > beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
            "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }

    Supplier <? > instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized(mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        if (autowireNecessary) {
            return autowireConstructor(beanName, mbd, null, null);
        } else {
            return instantiateBean(beanName, mbd);
        }
    }

    // Candidate constructors for autowiring?
    Constructor <? > [] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    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);
}

instantiateBean源码如下所示,我们重点关注的是beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);这行代码。

java 复制代码
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);
    }
}

instantiate方法源码如下图所示,我们debug代码可以看到代码走到了用红色方框圈住的那行代码constructorToUse = clazz.getDeclaredConstructor();这行代码显然是为了获取类的无参构造器,我们学习反射的时候就知道,要创建实例,主要就是通过先拿到构造器来创建实例的。

上面拿到了构造器之后,紧接着就是走到return BeanUtils.instantiateClass(constructorToUse);这行代码,从调用的方法名就知道要通过构造器去创建实例对象,源码如下所示,ReflectionUtils.makeAccessible(ctor);这行代码相信大家也不陌生,如果反射要使用私有构造器去创建实例对象的话得先进行赋权,也就是setAccessible为true。这也就是为何反射不安全的原因。紧接着我们就重点看创建实例的代码,也就是return ctor.newInstance(argsWithDefaultValues);这行代码。

java 复制代码
public static < T > T instantiateClass(Constructor < T > ctor, Object...args) throws BeanInstantiationException {
    Assert.notNull(ctor, "Constructor must not be null");
    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);
        }
    } catch (InstantiationException ex) {
        throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
    } catch (IllegalAccessException ex) {
        throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
    } catch (IllegalArgumentException ex) {
        throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
    } catch (InvocationTargetException ex) {
        throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
    }
}

newInstance的源码如下所示,我们显然应该关注的是倒数第二行T inst = (T) ca.newInstance(initargs);

java 复制代码
@CallerSensitive
public T newInstance(Object...initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
    if (!override) {
        if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
            Class <? > caller = Reflection.getCallerClass();
            checkAccess(caller, clazz, null, modifiers);
        }
    }
    if ((clazz.getModifiers() & Modifier.ENUM) != 0)
        throw new IllegalArgumentException("Cannot reflectively create enum objects");
    ConstructorAccessor ca = constructorAccessor; // read volatile
    if (ca == null) {
        ca = acquireConstructorAccessor();
    }@
    SuppressWarnings("unchecked")
    T inst = (T) ca.newInstance(initargs);
    return inst;
}

创建完实例后如下图所示,可见这时Cource类只是刚实例化出来,还没有进行初始化(courceName会在afterPropertiesSet方法中被赋值),代码到这里就看完了实例化的过程。

六、属性填充

我们所举例的代码中,Student类中注入了Course类,因此我们关注Student类的实例创建及属性填充。我们再回到上面提到的doCreateBean源码中,如下所示,可以看到在Object exposedObject = bean;这行代码的下面有一行populateBean(beanName, mbd, instanceWrapper);这样的代码。

java 复制代码
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        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;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized(mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, () - > getEarlyBeanReference(beanName, mbd, bean));
    }

    // 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);
        }
    }

    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set < String > actualDependentBeans = new LinkedHashSet < > (dependentBeans.length);
                for (String dependentBean: dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                        "Bean with name '" + beanName + "' has been injected into other beans [" +
                        StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                        "] in its raw version as part of a circular reference, but has eventually been " +
                        "wrapped. This means that said other beans do not use the final version of the " +
                        "bean. This is often the result of over-eager type matching - consider using " +
                        "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

populateBean方法源码如下,这段代码中真正执行自动注入逻辑的代码是如下图所示代码

java 复制代码
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        } else {
            // Skip property population phase for null instance.
            return;
        }
    }

    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp: getBeanPostProcessorCache().instantiationAware) {
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }

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

    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

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

    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (InstantiationAwareBeanPostProcessor bp: getBeanPostProcessorCache().instantiationAware) {
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }
                pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    return;
                }
            }
            pvs = pvsToUse;
        }
    }
    if (needsDepCheck) {
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    if (pvs != null) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

真正去执行自动注入的组件是AutowiredAnnotationBeanPostProcessor,而AutowiredAnnotationBeanPostProcessor又是InstantiationAwareBeanPostProcessor的实现类,AutowiredAnnotationBeanPostProcessor类中的postProcessProperties()方法负责解析@Autowired和@Value等注解。当调用到getBeanPostProcessorCache().instantiationAware的postProcessAfterInstantiation方法时就会调用到 AutowiredAnnotationBeanPostProcessorpostProcessProperties() 方法,从而完成自动注入,也就是完成属性填充。如下图所示

七、Aware接口回调

我们上面看完了属性填充阶段的代码,接下来就该看初始化的方法了,不过在初始化之前会先进行Aware接口回调,我们通过代码来印证一下。

我们回到上面提到的doCreateBean源码内部,如下所示,我们找到刚才属性填充那一行代码的下一行代码,也就是populateBean方法下面的exposedObject = initializeBean(beanName, exposedObject, mbd);这行代码

java 复制代码
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        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;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized(mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, () - > getEarlyBeanReference(beanName, mbd, bean));
    }

    // 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);
        }
    }

    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set < String > actualDependentBeans = new LinkedHashSet < > (dependentBeans.length);
                for (String dependentBean: dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                        "Bean with name '" + beanName + "' has been injected into other beans [" +
                        StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                        "] in its raw version as part of a circular reference, but has eventually been " +
                        "wrapped. This means that said other beans do not use the final version of the " +
                        "bean. This is often the result of over-eager type matching - consider using " +
                        "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

我们进入到方法initializeBean内部,如下所示,我们在第一个else分支中可以看到invokeAwareMethods(beanName, bean);这么一行代码,从字面意思就可以看出来这是要执行Aware接口回调了。

java 复制代码
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;
}

我们debug代码走到Student类的初始化流程,看看代码执行到invokeAwareMethods方法内部时,我们可以看到代码会走setBeanName方法,而我们的Student类中因为实现了BeanNameAware接口,因此重写了setBeanName方法,因此代码走到这里就该去Student类中执行setBeanName方法了。

我们debug结果如下图所示,可以看到,确实是进入到Student类的setBeanName方法中去执行了。这就是Aware接口回调的简单应用。

八、初始化前处理器(BeanPostProcessor前置处理)

我们目前代码走到这里,Student类还没有完成初始化呢,而在初始化方法被调用之前,还有个步骤就是初始化前置处理器,我们从源码来看,我们先回到initializeBean方法源码,如下所示,这里面有一行代码是wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);这就是执行初始化前置处理器,我们这里没有举初始化前置处理所用到的例子(涉及到初始化前置处理器的场景包括我们的类中使用了@PostConstruct注解修饰一个初始化方法,这种场景下,执行@PostConstruct这个注解修饰的方法就发生在初始化前置处理器之中

java 复制代码
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;
}

九、初始化

在看完初始化前置处理器之后,我们紧接着就是看初始化的源码,我们还是回到initializeBean方法内部,如下所示,中间try中的那行invokeInitMethods(beanName, wrappedBean, mbd);代码就是执行初始化逻辑。

java 复制代码
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;
}

我们为验证这个,还是通过debug的方式来进行,我们进入到invokeInitMethods源码内部,在代码中间else分支中有一行((InitializingBean) bean).afterPropertiesSet();便是执行Student类中的afterPropertiesSet方法。

java 复制代码
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {

    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();
        }
    }

    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);
        }
    }
}

代码执行效果如下图所示,可以看到确实进入到afterPropertiesSet方法内部了。从而这里就完成了初始化的动作。

十、初始化后置处理器

我们demo中没有涉及到初始化后置处理器的场景,但其实我们最常见的AOP,就可能发生在这个阶段。初始化后置处理器的源码我们还是回到上面提到的initializeBean方法源码内部,如下所示,在差不多最下面有一行wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);代码,就是处理初始化后置处理器的。

java 复制代码
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;
}

经过以上步骤之后,我们的Bean就初始化完成了,也就准备就绪了。我这里只是举了一个比较简单的场景,更多复杂的场景大家可以自行研究学习。

相关推荐
Tracy-221 小时前
啥是Spring,有什么用,既然收费,如何免费创建SpringBoot项目,依赖下载不下来的解决方法,解决99%问题!
java·spring
未定义.2211 小时前
Java设计模式实战:策略模式在SimUDuck问题中的应用
java·设计模式·策略模式
码熔burning3 小时前
【NIO番外篇】之组件 Channel
java·nio·channel
卡尔曼的BD SLAMer4 小时前
问题 | 针对SSM(Spring + Spring MVC + MyBatis)框架的去Spring MVC强化版学习路线
java·spring·mvc·mybatis
春生野草4 小时前
0413-多态、Object类方法、访问权限修饰符、装箱拆箱、128陷阱
java·开发语言
烁3474 小时前
每日一题(小白)暴力娱乐篇25
java·数据结构·算法·娱乐
烁3474 小时前
每日一题(小白)暴力娱乐篇26
java·开发语言·算法·娱乐
小白的一叶扁舟5 小时前
Java设计模式全解析(共 23 种)
java·开发语言·设计模式·springboot
kkkkatoq5 小时前
设计模式 四、行为设计模式(2)
java·开发语言·设计模式
隔壁小王攻城狮6 小时前
完整源码停车场管理系统,含新能源充电系统,实现了停车+充电一体化
java·开源·iot·停车场系统·新能源汽车充电·停车场管理系统源码