Spring源码整体分析

spring 架构原理图


核心注解

常用注解

@Bean

使用 @Bean + @Configuration 的形式可以替代 xml 配置文件的形式

@Import

@Import:指示要导入的一个或多个组件类

Spring 提供了很多方式来定义 bean 的信息,包括 xml 配置文件,注解,网络,磁盘等,通过资源加载器加载这些资源中的 bean 信息到 BeanDefinitionRegistrar 中,BeanDefinitionRegistrar 就相当于 bean 的图纸(除此之外还有 SimpleAliasRegistry 和SingletonBeanRegistry 等其他保存 bean 定义信息的图纸),无论是 xml 还是注解方式定义的 bean 信息,最终进入的都是 BeanDefinitionRegistrar 这种类型中保存,在这其中定义的只是 bean 的类型、名称信息,bean 的属性值等信息不在其中定义。

在 @Import 中可以直接传入 bean 的 class,也可以传入 BeanDefinitionRegistry 加载其中所有的 bean 定义信息,使用如下

@Import({Person.class, Config.MyBeanDefinitionRegistry.class})
static class MyBeanDefinitionRegistry implements ImportBeanDefinitionRegistrar {
	@Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) 	{
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        
        // 手动定义 bean 信息
        rootBeanDefinition.setBeanClass(Person.class);
        registry.registerBeanDefinition("person01", rootBeanDefinition);
    }
}

@Lookup

当单例的组件中需要依赖非单例的组件时,使用此注解实现,注意,一旦使用此注解,则对应的非单实例属性不能使用 @Autowired 注入且 @Lookup 需要标注在对应属性的 getXxx() 方法上,使用如下

public class MainTest {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        Person p1 = context.getBean(Person.class);
        Person p2 = context.getBean(Person.class);

        System.out.println(p1.getCat() == p2.getCat()); // false
    }
}

Cat 类

@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 原型模式,非单例
@Component
public class Cat {
    private String name;

    public String getName() {
        return name;
    }

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

Person 依赖 Cat

package com.dhj.demo.bean;

import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;

/**
 * @description: Person
 * @author: dhj
 * @date: 2021/11/13 15:21
 * @version: v1.0
 */
@Component
public class Person {
    private String name;

    private Cat cat;

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

    @Override
    public String toString() {
        return "Person{" +
            "name='" + name + '\'' +
            '}';
    }

    @Lookup
    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

spring 大致容器类关系图


spring 核心组件&接口

org.springframework.core.io.Resource

此接口代表的是一个资源的抽象,Spring 将不同资源(磁盘,网络,xml 配置等)加载为一个 Resource

org.springframework.core.io.ResourceLoader

ResourceLoader 用于加载 Resource 中的资源,ResourceLoader 使用了策略模式

策略模式简介

策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理

策略模式的主要角色如下

抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。

具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。

环境(Context)类:持有一个策略类的引用,最终给客户端调用

ResourceLoader 接口中定义了对资源的各种抽象策略,ResourceLoader 的具体实现类中则是对抽象策略的各种具体实现。用以应对不同资源的加载,例如默认的实现类 DefaultResourceLoader 就可以对 url 资源和 classpath下的资源进行加载。

此时还缺少一个环境类,这个环境类就是 AbstractApplicationContext,在该环境类中,引用了抽象策略 ResourceLoader 且在类创建时,就指向了一个具体的策略实例

/**
	 * Create a new AbstractApplicationContext with no parent.
	 */
public AbstractApplicationContext() {
    this.resourcePatternResolver = getResourcePatternResolver();
}

org.springframework.beans.factory.BeanFactory

用于访问Spring bean容器的根接口,该接口的主要类图如下

主要是一些工厂和各种 ioc 容器,而由此牵涉出来的其他类图如下

其中 BeanDefinitionRegistry,SingletonBeanRegistry 等都相当于是 bean 的图纸,保存 bean 的定义信息,最终通过层层的继承,实现,组合等方式,得到了一个 DefaultListableBeanFactory(总档案馆,与多个档案馆、工厂都有联系),该类中就保存了 ioc 中的核心信息(包括所有 bean 的定义信息等),部分相关属性如下

/** Map of bean definition objects, keyed by bean name. */
// 保存所有 bean 的定义信息,按照 bean 名称放入 Map 中
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

/** Map of singleton and non-singleton bean names, keyed by dependency type. */
// 保存 bean 的定义信息,按照 bean 的类型放入 Map 中
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

/** Map of singleton-only bean names, keyed by dependency type. */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

/** List of bean definition names, in registration order. */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

/** List of names of manually registered singletons, in registration order. */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);

/** Cached array of bean definition names in case of frozen configuration. */
@Nullable
private volatile String[] frozenBeanDefinitionNames;

BeanFactory 的另一个接口实现 AutowireCapableBeanFactory 则定义了 bean 自动装配的能力,而我们常用的对注解进行支持的 AnnotationConfigApplicationContext 的父类 GenericApplicationContext 中,就通过组合的方式(合成复用原则)组合了上面提到的总档案馆 DefaultListableBeanFactory, 部分源码如下

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

	private final DefaultListableBeanFactory beanFactory;
	
	....
}

这也就相当于 AnnotationConfigApplicationContext 拥有了自动装配的能力

spring 资源加载 & bean 信息定义流程

以常用的 ClassPathXmlApplicationContext 为例,该类的实例就是一个 spring 容器

 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

从类路径下的 bean.xml 中加载资源,最终构造成一个 ioc 容器

构造器底层调用如下

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

继续深入,如下

public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
            // 刷新容器
			refresh();
		}
	}

传入资源名 configLocations 也就是 bean.xml,且 refresh 为 true,这代表在构建 spring 容器时就会刷新

refresh() 方法部分如下

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        prepareRefresh();

        // 刷新 bean 工厂(堆栈点)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

        ....

最主要是 obtainFreshBeanFactory() 方法,通过 debug 堆栈继续跟踪,其底层调用如下

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}

继续跟踪,调用的是 refreshBeanFactory(),依旧是刷新 bean 工厂,源码如下

@Override
protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        /*
            要刷新容器,就先创建 bean 工厂
            因为是 DefaultListableBeanFactory 类型的,根据前面的源码查看以及类图分析
            DefaultListableBeanFactory 实际上就是资源加载后的所有 bean 定义信息(图纸)存放的总档案馆
            这里是先创建,还没有保存 bean 信息
            */
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);

        /*
            加载所有 bean 的定义信息(堆栈点)
            */
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

DefaultListableBeanFactory 内部的档案馆定义如下

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

使用 bean 的名字作为 key

创建了档案馆之后,才会将 bean 的定义信息加载进档案馆,调用的是 loadBeanDefinitions() 方法,底层如下

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // 创建读取器,读取 xml 资源
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);
    
    // 加载 bean 的定义信息(堆栈点)
    loadBeanDefinitions(beanDefinitionReader);
}

创建读取器后,还为该读取器设置了一个资源加载器

beanDefinitionReader.setResourceLoader(this);

这说明读取器就是通过资源加载器来加载 xml 配置文件资源的

继续堆栈跟踪如下

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
    
        // 获取所有 xml 配置文件的位置,因为是数组形式,说明可以传入多个配置
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
            
            // 读取配置文件(堆栈点)
			reader.loadBeanDefinitions(configLocations);
		}
	}

堆栈跟踪

@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
	Assert.notNull(locations, "Location array must not be null");
	int count = 0;
	for (String location : locations) {
        // 加载每一个配置文件(堆栈点)
		count += loadBeanDefinitions(location);
	}
	return count;
}

堆栈跟踪,部分源码如下

// 判断资源加载器的类型,可以加载不同类型的资源
if (resourceLoader instanceof ResourcePatternResolver) {
    // Resource pattern matching available.
    try {
        // 根据配置文件路径加载资源
        Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
        // 从资源中加载 bean 定义信息(堆栈点)
        int count = loadBeanDefinitions(resources);
        if (actualResources != null) {
            Collections.addAll(actualResources, resources);
        }
        if (logger.isTraceEnabled()) {
            logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
        }
        return count;
    }
    catch (IOException ex) {
        throw new BeanDefinitionStoreException(
            "Could not resolve bean definition resource pattern [" + location + "]", ex);
    }
}

堆栈跟踪

try {
    InputStream inputStream = encodedResource.getResource().getInputStream();
    try {
        InputSource inputSource = new InputSource(inputStream);
        if (encodedResource.getEncoding() != null) {
            inputSource.setEncoding(encodedResource.getEncoding());
        }
        // 加载资源中 bean 的定义信息(堆栈点)
        return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    }
    finally {
        inputStream.close();
    }
}
catch (IOException ex) {
    throw new BeanDefinitionStoreException(
        "IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
    currentResources.remove(encodedResource);
    if (currentResources.isEmpty()) {
        this.resourcesCurrentlyBeingLoaded.remove();
    }
}

堆栈跟踪

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    throws BeanDefinitionStoreException {

    try {
        // 将 xml 资源加载为 dom 文档对象(xml 解析)
        Document doc = doLoadDocument(inputSource, resource);

        //注册 bean 的定义信息(堆栈点)
        int count = registerBeanDefinitions(doc, resource);
        if (logger.isDebugEnabled()) {
            logger.debug("Loaded " + count + " bean definitions from " + resource);
        }
        return count;
    }

堆栈跟踪

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    int countBefore = getRegistry().getBeanDefinitionCount();
    
    // 通过读取 Docment 对象,注册 bean 的定义信息(堆栈点)
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    return getRegistry().getBeanDefinitionCount() - countBefore;
}

堆栈跟踪

@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    // 得到 Document 元素,注册 bean 信息(堆栈点)
    doRegisterBeanDefinitions(doc.getDocumentElement());
}

堆栈跟踪

preProcessXml(root);

// 解析 dom 对象(堆栈点)
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);

this.delegate = parent;

在解析 dom 对象时,还传入了一个 delegate 对象,这实际上是一个代理类,规定了 spring 配置文件中能被识别的标签,其源码部分如下

public static final String MULTI_VALUE_ATTRIBUTE_DELIMITERS = ",; ";

	/**
	 * Value of a T/F attribute that represents true.
	 * Anything else represents false. Case seNsItive.
	 */
	public static final String TRUE_VALUE = "true";

	public static final String FALSE_VALUE = "false";

	public static final String DEFAULT_VALUE = "default";

	public static final String DESCRIPTION_ELEMENT = "description";

	public static final String AUTOWIRE_NO_VALUE = "no";

	public static final String AUTOWIRE_BY_NAME_VALUE = "byName";

	public static final String AUTOWIRE_BY_TYPE_VALUE = "byType";

	public static final String AUTOWIRE_CONSTRUCTOR_VALUE = "constructor";

	public static final String AUTOWIRE_AUTODETECT_VALUE = "autodetect";

	public static final String NAME_ATTRIBUTE = "name";

	public static final String BEAN_ELEMENT = "bean";

继续堆栈跟踪

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    if (delegate.isDefaultNamespace(root)) {
        NodeList nl = root.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (node instanceof Element) {
                Element ele = (Element) node;
                if (delegate.isDefaultNamespace(ele)) {
                    // 解析元素(可能的堆栈点)
                    parseDefaultElement(ele, delegate);
                }
                else {
                    // 如果没有在 delegate 中找到对应的标准,则代表该元素为自定义元素(可能的堆栈点)
                    delegate.parseCustomElement(ele);
                }
            }
        }
    }
    else {
        delegate.parseCustomElement(root);
    }
}

这里就开始真正的解析 dom 对象了,根据传入的 delegate 对象作为标准来解析 dom 对象中的元素,

堆栈跟踪

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }

    // 该 dom 元素在 delegate 中有对应的定义,可以被解析为 bean 的图纸相关信息(可能的堆栈点) 
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    }
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        // recurse
        doRegisterBeanDefinitions(ele);
    }
}

堆栈跟踪

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    // 将 dom 元素解析为一个 BeanDefinitionHolder 对象
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            // Register the final decorated instance.
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name '" +
                                     bdHolder.getBeanName() + "'", ele, ex);
        }
        // Send registration event.
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

BeanDefinitionHolder 部分源码如下

public class BeanDefinitionHolder implements BeanMetadataElement {

	private final BeanDefinition beanDefinition;

	private final String beanName;

	@Nullable
	private final String[] aliases;

	.....

dom 元素最近会被解析为 beanName + BeanDefinition 的形式

继续调用 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); 将 bean 信息注册到档案馆中,registerBeanDefinition() 方法实现如下

public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {

    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    
    // 按照 bean名字+bean定义信息的形式来注册
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // Register aliases for bean name, if any.
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}

registerBeanDefinition() 方法有不同的实现,这里使用的是 DefaultListableBeanFactory 中的实现

在 DefaultListableBeanFactory 的 registerBeanDefinition() 方法中,正常情况下,最终会将 bean 信息放入 Map 结构的档案馆中

this.beanDefinitionMap.put(beanName, beanDefinition);

无论是 DefaultListableBeanFactory 还是其他的一些实现类,他们都实现的是 BeanDefinitionRegistry,可以说 BeanDefinitionRegistry 就是所有 bean 定义信息的档案馆,至此,完成了整个的从 spring xml 配置文件最终被加载为 bean 定义信息的流程。

流程图总结

bean 实例化 & 属性自动装配过程

前面的流程依然是一样的,调用 spring 容器的构造器,先刷新创建 bean 工厂

public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

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

完成 bean 工厂的初始化

// bean 工厂的初始化完成了,组件都准备好了
finishBeanFactoryInitialization(beanFactory);

跟踪堆栈,finishBeanFactoryInitialization() 方法内部继续调用

// 实例化所有剩余的(非延迟初始化)单例,这里的剩余指的是在这之前,已经实例化了 bean 后置处理器的实例
beanFactory.preInstantiateSingletons();

跟踪 preInstantiateSingletons() 源码

@Override
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // 初始化所有非懒加载的 bean
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 通过 bean 定义信息,判断 bean 是否不是抽象的,是单例的,不是懒加载的
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 继续判断是否是工厂 bean
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    final 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 {
                // 不是工厂 bean 直接获取 bean 实例
                getBean(beanName);
            }
        }
    }

关于工厂 bean,以下就是一个工厂 bean

public class HelloFactoryBean implements FactoryBean<Cat> {
 @Override
 public Cat getObject() throws Exception {
     return new Cat();
 }

 @Override
 public Class<?> getObjectType() {
     return Cat.class;
 }
}

相比较一般的普通 bean,例如 Person 这种直接将自身注册到 spring 容器中的,工厂 bean 注册到容器中的并非自身,而是 getObject() 方法的返回值,注册组件的类型就是 getObjectType 的返回值,实现了 FactoryBean 接口的类,就能通过重写这两个方法来自定义注册组件到 spring 容器中

在 getBean() 中,走的便是 bean 工厂中 doGetBean,createBean() 那一套流程

....
// Create bean instance.
if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, () -> {
        try {
            // 熟悉的 lambda 表达式
            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;
        }
    });
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
.....

跟踪 createBean() 源码

.....
try {
    // 创建 bean 实例
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isTraceEnabled()) {
        logger.trace("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
}
.....

继续跟踪 doCreateBean()

if (instanceWrapper == null) {
    // 创建 bean 实例
	instanceWrapper = createBeanInstance(beanName, mbd, args);
}
.......

跟踪 createBeanInstance()

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

// 无参构造创建
return instantiateBean(beanName, mbd);

继续跟踪 instantiateBean(),默认使用的是无参构造创建对象,最底层使用的是反射(也可以使用 cglib),如果有构造参数注入的方式,则使用 autowireConstructor(),底层使用的是 BeanUtils 来创建默认的空参构造的实例,相关源码如下

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

通过上述流程 Person 对象的实例已经被创建,如果有属性的自动装配,那么将继续执行 doCreateBean() 方法,也就是如下逻辑

// 初始化 bean 实例,此时 bean 中的属性还没有被赋值
Object exposedObject = bean;
try {
    // 填充 bean (属性赋值)
    populateBean(beanName, mbd, instanceWrapper);
    exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
    if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
        throw (BeanCreationException) ex;
    }
    else {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
    }
}
......

跟踪 populateBean() 方法

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

	// 从 bean 的定义信息中得到所有属性的键值对:属性名 + 属性值
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    .......

    if (pvs != null) {
        // 属性赋值,底层使用反射(xml 版本)
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

以上是 xml 版本的 bean 实例化和属性赋值,注解方式调用的则是 populateBean() 中的另外一段逻辑,如下

// 使用 AutowiredAnnotationBeanPostProcessor 来完成基于注解的自动装配功能
for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
        // 堆栈点
        PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
        if (pvsToUse == null) {
            if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                return;
            }
        }
        pvs = pvsToUse;
    }
}

跟踪堆栈

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // 得到自动装配的元数据信息,实际上就是查找类中标注的注解信息,例如 @Autowired
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    try {
        metadata.inject(bean, beanName, pvs);
    }
    catch (BeanCreationException ex) {
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
    }
    return pvs;
}

至此,spring 中基本的 bean 实例化和属性赋值的流程就完成了

org.springframework.context.ApplicationContext

ApplicationContext 类关系图如下

通过关系图可知,ApplicationContext 既包含了 bean 定义信息(ListableBeanFactory > DefaultListableBeanFactory),也包含了资源加载器(ResourceLoader)还包括国际化器(MessageSource)以及 Bean 工厂(通过组合的方式获得了自动装配功能 > AutowireCapableBeanFactory)

org.springframework.beans.factory.Aware & org.springframework.beans.factory.config.BeanPostProcessor

Aware

一个标记超级接口,指示 bean 有资格通过回调样式的方法被特定框架对象的 Spring 容器通知。实际的方法签名由各个子接口确定,但通常应仅由一个接受单个参数的返回空值的方法组成。简单来说,我们想要在代码中得到 Spring 管理的一些组件甚至是 Spring 容器时,除了 @Autoware 自动注入外,对应一些特定的组件,就可以实现其对应的接口,重写抽象方法,通过回调的方式得到对应组件的实例

BeanPostProcessor

后置增强组件,对 bean 组件进行后置增强,Aware 的回调注入依靠该接口的实现完成

例如通过 ApplicationContextAware 获取 ApplicationContext 如下

public class Person implements ApplicationContextAware {
    ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
.....

相关的 Aware 类图

下面通过 Aware 来追踪 spring 加载和实例化 bean 以及 BeanPostProcessor 运作的时机的过程,依旧使用 ClassPathXmlApplicationContext 来进行调试

 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

堆栈跟踪

public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

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

这部分就是上面提到过的创建 bean 工厂,加载 bean 的定义信息到档案馆

// 完成 bean 工厂的初始化后(堆栈点)
finishBeanFactoryInitialization(beanFactory);
// 初始化所有的单实例 bean(堆栈点)
beanFactory.preInstantiateSingletons();

preInstantiateSingletons() 部分源码如下

// 遍历档案馆 bean 定义信息中的 beanName 集合,逐一加载 bean 实例
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) {
                final 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) {
                    // 获取 bean 实例(可能的堆栈点)
                    getBean(beanName);
                }
            }
        }
        else {
            // 获取 bean 实例(可能的堆栈点)
            getBean(beanName);
        }
    }
}

可以看出,在 spring 底层,实际上早就开始获取 bean 了

getBean() 底层调用的实际上是 doGetBean() 方法, 部分源码如下

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                          @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // 检查缓存中是否有已经存在的单实例
    Object sharedInstance = getSingleton(beanName);
    .....

继续追踪 getSingleton() 底层,调用到了 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry 中的如下属性

/**
缓存单实例,bean 的 name 为 key,bean 的实例为 value
这是一个单例对象池,也就是 spring 底层的 ioc 容器(单例池)
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

回到 doGetBean() 方法,

// Create bean instance.
if (mbd.isSingleton()) {
    // 获取 bean 的单实例
    sharedInstance = getSingleton(beanName, () -> {
        try {
            // 创建 bean 实例(堆栈点)
            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;
        }
    });
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

createBean() 是一个 lambda 表达式,在外部继续调用 getSingleton() 方法,追踪关键源码如下

try {
    // 从对象工厂中得到 bean 实例
    singletonObject = singletonFactory.getObject();
    newSingleton = true;
}

这里的 singletonFactory 实际就是传入的 createBean Lambda 表达式,跟踪堆栈,调用的实际上是 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 中的 createBean() 方法,部分源码如下

try {
   Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   if (logger.isTraceEnabled()) {
      logger.trace("Finished creating instance of bean '" + beanName + "'");
   }
   return beanInstance;
}

跟踪 doCreateBean() 方法,关键部分源码如下

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
    // 创建 bean 实例
    instanceWrapper = createBeanInstance(beanName, mbd, args);
}

跟踪 instantiateBean() 方法,关键源码如下

if (resolved) {
    if (autowireNecessary) {
        return autowireConstructor(beanName, mbd, null, null);
    }
    else {
        // 实例化一个 bean
        return instantiateBean(beanName, mbd);
    }
}

instantiateBean() 完整源码如下

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
                // 使用策略模式来创建 bean 实例
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

spring 将创建 bean 的不同方式封装为不同的策略(jdk 反射创建,cglib 创建子类实例等(代理对象)),根据当前环境的不同使用不同的策略来创建 bean

这里使用的是 SimpleInstantiationStrategy 中的 bean 创建策略,调用的 instantiate() 方法,源码如下

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    if (!bd.hasMethodOverrides()) {
        Constructor<?> constructorToUse;
        synchronized (bd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse == null) {
                final Class<?> clazz = bd.getBeanClass();
                if (clazz.isInterface()) {
                    throw new BeanInstantiationException(clazz, "Specified class is an interface");
                }
                try {
                    if (System.getSecurityManager() != null) {
                        constructorToUse = AccessController.doPrivileged(
                            (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                    }
                    else {
                        // 拿到构造器
                        constructorToUse = clazz.getDeclaredConstructor();
                    }
                    bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                }
                catch (Throwable ex) {
                    throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                }
            }
        }
        // 使用工具类创建 bean 实例
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // Must generate CGLIB subclass.
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}

到此实际上就创建了 bean 的实例,只不过内部还有很多细节,但我们更加应着眼于全局

对于实现了 Aware 相关接口的 bean,其属性回调赋值的流程如下

回到 doCreateBean() 方法处,在 bean 实例创建后,跟踪堆栈,继续调用了 initializeBean() 方法对 bean 进行初始化

跟踪堆栈,在初始化时,使用到了 ApplicationContextAwareProcessor,这就是 BeanPostProcessor 的实现类,在该类中对实现了 Aware 的 bean 进行处理(后置处理),调用了 invokeAwareInterfaces() 方法,源码如下

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    }
    if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    }
    if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    }
    if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    }
    if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    }
    if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    }
}

判断实现了Aware 接口的 bean 类型,根据不同类型来执行对应的回调传入对应的实例

流程图总结如下

生命周期主要接口

org.springframework.beans.factory.config.BeanPostProcessor

后置增强组件,其每一个子接口增强器在合适的时机运行,在于改变实例化后的 bean 组件,例如对实现了 Aware 接口的组件进行回调属性赋值

org.springframework.beans.factory.config.BeanFactoryPostProcessor

后置增强工厂,对 BeanFactory 进行后置增强

org.springframework.beans.factory.InitializingBean

初始化 bean 组件后,对组件进行后续的设置,在于 bean 组件实例化后的额外的处理而不是改变 bean 组件

后面我们将通过上面几个关键接口及其子接口来研究 spring 中 bean 的整个生命周期中被怎样的干预,改变的,通过掌握这整个流程,加深对 spring 运行机制的理解。


bean 生命周期

工厂后置处理接口解析之 BeanFactoryPostProcessor

继续通过 debug 的方式来解析上面三个接口的执行过程,实现上述三个接口,放入容器中,启动加载 spring 容器,debug 跟踪源码

首先,依旧是刷新创建工厂

public ClassPathXmlApplicationContext(
    String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
    throws BeansException {

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

工厂刷新创建成功后,就开始调用相关后置增强处理方法了,可以看出,最先调用的实际上是 bean 工厂的后置增强处理:BeanDefinitionRegistryPostProcessor,这也很好理解,bean 工厂是造 bean 实例的,要是想要对 bean 工厂进行一些定制化的增强,肯定要在 bean 实例化之前或者说最初就进行增强逻辑的调用,以便保证这种增强在可能对 bean 实例化有影响的情况下起作用,倘若在 bean 实例化后再增强 bean 工厂,那这种影响就不会生效

....
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
    // Allows post-processing of the bean factory in context subclasses.
    postProcessBeanFactory(beanFactory);

    // 获取容器中已经加载过的 bean 工厂后置增强器对 bean 工厂进行增强
    invokeBeanFactoryPostProcessors(beanFactory);
    .....

跟踪堆栈,invokeBeanFactoryPostProcessors() 调用的源码如下

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    	/*
        继续调用内部类 PostProcessorRegistrationDelegate 的 invokeBeanFactoryPostProcessors() 方法
        将 bean 工厂传入,同时获取容器中的 bean 工厂后置处理器:getBeanFactoryPostProcessors()
		*/
		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 (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

下面,开始真正的调用 bean 工厂后置处理的逻辑(重要部分通过注释标注)

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    	// 意思:如果有的话,首先调用 BeanDefinitionRegistryPostProcessors。
		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            
            // 先得到底层默认有的 BeanFactoryPostProcessor 放入 regularPostProcessors 中(暂时忽略)
			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.、
            /*
            意思:
            不要在此处初始化 FactoryBeans:我们需要保留所有常规 bean 未初始化以让 bean 工厂后处理器应用于它们!将实现 PriorityOrdered、Ordered 和其余部分的 BeanDefinitionRegistryPostProcessor 分开。
            */
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// 从 bean 工厂中获取所有的 BeanDefinitionRegistryPostProcessor
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
                // 判断所有的 bean 工厂后置处理器是否实现了 PriorityOrdered 接口,该接口用于后置处理器的优先级排序
                // 值越小优先级越高
				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);
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
                // 继续判断 bean 工厂后置处理器是否实现了 Ordered 接口,也是用于排序并且若之前实现过了 PriorityOrdered 接
                // 口,那么以 PriorityOrdered 接口的排序为准,因为:!processedBeans.contains(ppName)
				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);
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 意思: 最后,调用所有其他 BeanDefinitionRegistryPostProcessor 直到不再出现。
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
                        // spring 中所有组件的获取都是通过 getBean() 从容器中获取,容器中有就直接得到,没有则创建,这就是 spring 的循环依赖
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
                // 将剩下的既没有实现 PriorityOrdered 接口,也没有实现 Ordered 接口的 bean 工厂后置处理,利用类名进行排序
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
                // 开始调用
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				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!
    /*
    意思:不要在此处初始化 FactoryBeans:我们需要保留所有常规 bean 未初始化以让 bean 工厂后处理器应用于它们!
    */
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
    /*
    意思:将实现 PriorityOrdered、Ordered 和其余部分的 BeanFactoryPostProcessors 分开。
    */
		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.
    	// 先调用实现了 PriorityOrdered 的 BeanFactoryPostProcessors
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    	// 开始调用
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    	// 再调用实现 Ordered 的 BeanFactoryPostProcessors
		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.
    	// 最终调用其他的 BeanFactoryPostProcessors
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
    	/*
    	开始调用;没有实现优先级接口的 BeanFactoryPostProcessors 中的方法就会被调用
    	先是 postProcessBeanDefinitionRegistry() 方法,后是 postProcessBeanFactory() 方法
    	*/
		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();
	}

整个过程无非就是获取实现了 BeanFactoryPostProcessor 接口的实例,调用其中的 postProcessBeanDefinitionRegistry() 或postProcessBeanFactory() 方法,调用之前进行优先级接口的一些排序

我们需要知道的是最先加载的是实现了 BeanDefinitionRegistryPostProcessor 接口的组件(实际上 BeanDefinitionRegistryPostProcessor 实现的也是 BeanFactoryPostProcessor 这里 spring 通过 BeanDefinitionRegistryPostProcessor 将直接实现了 BeanFactoryPostProcessor 的实例进行区分),在 bean 工厂创建完成后就被加载了,先执行了其中的 postProcessBeanDefinitionRegistry(),再执行了 postProcessBeanFactory()

然后执行的才是直接实现了 BeanFactoryPostProcessor 接口的实例中的 postProcessBeanFactory()

bean 工厂的典型应用就是 Configuration 配置类的后置处理,被 @Configuration 标注的配置类,会被 ConfigurationClassPostProcessor 进行后置处理,解析其中的配置,这也是属于 bean 工厂的后置处理,在工厂刷新创建成功后就先解析配置类中的配置,保证后续 bean 实例的准确创建,这其中的后置处理逻辑,调用的就是 ConfigurationClassPostProcessor 中的 postProcessBeanDefinitionRegistry() 方法(对 bean 工厂实行后置处理,加载配置);

生命周期接口解析之 BeanPostProcessor 的注册

关于 bean 工厂的后置增强,前面已经说过了,接下来便是 bean 的后置增强过程

依旧从刷新工厂开始

public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

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

刷新工厂时,便进入后置增强逻辑

.....
try {
    // Allows post-processing of the bean factory in context subclasses.
    postProcessBeanFactory(beanFactory);

    // 调用 bean 工厂的后置处理逻辑
    invokeBeanFactoryPostProcessors(beanFactory);

    // 注册  bean 的后置处理器
    registerBeanPostProcessors(beanFactory);
    .....

关于 bean 的后置处理器的 注册,紧接在 bean 工厂后置处理逻辑执行完毕后调用

registerBeanPostProcessors() 源码如下,其 api 文档很关键

/**
	 * Instantiate and register all BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before any instantiation of application beans.
	 实例化并注册所有 BeanPostProcessor bean,如果给出,则遵守显式顺序
	 必须在应用程序 bean 的任何实例化之前调用
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

其中 PostProcessorRegistrationDelegate 也很关键,它代理执行了所有的后置增强器的功能,在 bean 工厂的后置处理中,也是使用的 PostProcessorRegistrationDelegate 来代理执行的

继续追踪 PostProcessorRegistrationDelegate 中的 registerBeanPostProcessors() 方法,大体上依然是遍历所有的 bean 后置处理,根据其实现的 PriorityOrdered 或 Ordered 接口进行排序

public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // 获取到容器中所有的 BeanPosyProcesser 名字
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    // 遍历所有的 bean 后置处理,得到其中实现了 PriorityOrdered,Ordered 接口的,分隔到不同的集合中
    // 在这里实现 PriorityOrdered 接口的 bean 后置处理器就先被实例化了
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                // 内部后置处理器
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            // 无序的 bean 后置处理器
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 先注册实现了 PriorityOrdered 的 bean 后置处理器 
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // 再注册实现了 Ordered 接口的 bean 后置处理
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        // 获取 bean 后置处理器的实例
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        // 添加到集合中
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // 注册普通的 bean 后置处理器
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // 注册所有的内部 bean 后置处理
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

registerBeanPostProcessors 源码如下

private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
    	// 遍历 BeanPostProcessor 添加到 bean 工厂中
		for (BeanPostProcessor postProcessor : postProcessors) {
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}

以上就是 bean 后置处理被注册的流程,所谓的 bean 后置处理器的注册,实际上就是将 bean 后置处理器进行分类排序然后保存到 bean 工厂中。

生命周期接口解析之 SmartInstantiationAwareBeanPostProcessor (一)

以上是 BeanPostProcesser 的注册,下面继续解析 BeanPostProcesser 中后置处理逻辑的执行时机

首先是常规流程

// 创建 ioc 容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
// 刷新容器
public ClassPathXmlApplicationContext(
    String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
    throws BeansException {

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

refresh() 内部

.....
try {
    // 
    postProcessBeanFactory(beanFactory);

    // Invoke factory processors registered as beans in the context.
    invokeBeanFactoryPostProcessors(beanFactory);

    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);

    // Initialize message source for this context.
    initMessageSource();

    // Initialize event multicaster for this context.
    initApplicationEventMulticaster();

    // Initialize other special beans in specific context subclasses.
    onRefresh();

    // 检查侦听器 bean 并注册(堆栈点)
    registerListeners();

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

    // Last step: publish corresponding event.
    finishRefresh();
}
.......

跟踪 registerListeners() 源码

/**
	 *添加实现 ApplicationListener 作为侦听器的 bean。不影响其他监听器,可以不加bean
	 */
protected void registerListeners() {
    //首先注册静态指定的侦听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 不要在此处初始化 FactoryBeans:我们需要保留所有常规 bean 未初始化以让后处理器应用于它们!
    // 根据 bean 的类型获取 bean 名称,这里是获取 ApplicationListener 类型的 beanName
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // Publish early application events now that we finally have a multicaster...
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

深入追踪 getBeanNamesForType() 方法源码,如下

private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
    List<String> result = new ArrayList<>();

    // 遍历 beanDefinitionNames,也就是 bean 定义的名称
    for (String beanName : this.beanDefinitionNames) {
        // Only consider bean as eligible if the bean name
        // is not defined as alias for some other bean.
        if (!isAlias(beanName)) {
            try {
                // 通过 bean 名称来获取 bean 的定义信息
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // Only check bean definition if it is complete.
                if (!mbd.isAbstract() && (allowEagerInit ||
                                          (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
                                          !requiresEagerInitForType(mbd.getFactoryBeanName()))) {
                    boolean isFactoryBean = isFactoryBean(beanName, mbd);
                    BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                    boolean matchFound = false;
                    boolean allowFactoryBeanInit = allowEagerInit || containsSingleton(beanName);
                    boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();
                    if (!isFactoryBean) {
                        if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
                            // 再检查 bean 的定义信息是否为指定的类型(堆栈点)
                            matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                        }
                    }
                    else  {
                        if (includeNonSingletons || isNonLazyDecorated ||
                            (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
                            matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                        }
                        if (!matchFound) {
                            // In case of FactoryBean, try to match FactoryBean instance itself next.
                            beanName = FACTORY_BEAN_PREFIX + beanName;
                            matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                        }
                    }
                    if (matchFound) {
                        // 如果是指定类型,就将该 bean 的名称放入返回的结果集合中
                        result.add(beanName);
                    }
                }
            }
            catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
                if (allowEagerInit) {
                    throw ex;
                }
                // Probably a placeholder: let's ignore it for type matching purposes.
                LogMessage message = (ex instanceof CannotLoadBeanClassException) ?
                    LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
                LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName);
                logger.trace(message, ex);
                onSuppressedException(ex);
            }
        }
    }

追踪 isTypeMatch() 部分源码

.....
if (predictedType == null) {
    // 预测 bean 的类型(堆栈点)
    predictedType = predictBeanType(beanName, mbd, typesToMatch);
    if (predictedType == null) {
        return false;
    }
}
......

跟踪 predictBeanType()

@Override
@Nullable
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
    Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
    if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        boolean matchingOnlyFactoryBean = typesToMatch.length == 1 && typesToMatch[0] == FactoryBean.class;
        // 遍历所有的 bean 后置处理器
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            // 匹配 SmartInstantiationAwareBeanPostProcessor 类型的后置处理器
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                // 调用其中的 predictBeanType() 方法来预测类型
                Class<?> predicted = ibp.predictBeanType(targetType, beanName);
                if (predicted != null &&
                    (!matchingOnlyFactoryBean || FactoryBean.class.isAssignableFrom(predicted))) {
                    return predicted;
                }
            }
        }
    }
    return targetType;
}

在这里,执行了 BeanPostProcesser 中的第一个处理器方法,为 SmartInstantiationAwareBeanPostProcessor 中的 predictBeanType() 方法

predictBeanType() 的 bean 类型的预测只针对还没有完成实例化创建的组件,主要作用在于组件实例化创建之前,还能够决定组件的类型,详细流程解析如下

主要逻辑在 doGetBeanNamesForType() 方法中, 部分源码如下

.....
// 先判断是否为一个工厂 bean
if (!isFactoryBean) {
    if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
        matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
    }
}
else  {
    // 满足条件的才会执行 isTypeMatch 的类型预测逻辑,主要条件为 isSingleton(beanName, mbd, dbd)
    if (includeNonSingletons || isNonLazyDecorated ||
        (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
        matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
    }
    if (!matchFound) {
        // In case of FactoryBean, try to match FactoryBean instance itself next.
        beanName = FACTORY_BEAN_PREFIX + beanName;
        matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
    }
}
if (matchFound) {
    result.add(beanName);
}
......

追踪 isSingleton()

private boolean isSingleton(String beanName, RootBeanDefinition mbd, @Nullable BeanDefinitionHolder dbd) {
    return (dbd != null ? mbd.isSingleton() : isSingleton(beanName));
}

上面的三目运算无非就是通过 bean 定义信息或者 beanName 来作为判断依据,因此继续深入 isSingleton(),首先是空参的 isSingleton()

// 直接通过 BeanDefinition 本身的 scope 属性值来判断是否为单实例的
@Override
public boolean isSingleton() {
    return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
}

然后是有参的 isSingleton()

@Override
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);

    // 通过 bean 名称在单例池中获取 bean 实例
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null) {
        if (beanInstance instanceof FactoryBean) {
            return (BeanFactoryUtils.isFactoryDereference(name) || ((FactoryBean<?>) beanInstance).isSingleton());
        }
        else {
            return !BeanFactoryUtils.isFactoryDereference(name);
        }
    }

    // No singleton instance found -> check bean definition.
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
        // No bean definition found in this factory -> delegate to parent.
        return parentBeanFactory.isSingleton(originalBeanName(name));
    }

    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

    // In case of FactoryBean, return singleton status of created object if not a dereference.
    if (mbd.isSingleton()) {
        if (isFactoryBean(beanName, mbd)) {
            if (BeanFactoryUtils.isFactoryDereference(name)) {
                return true;
            }
            FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
            return factoryBean.isSingleton();
        }
        else {
            return !BeanFactoryUtils.isFactoryDereference(name);
        }
    }
    else {
        return false;
    }
}

以上就说明了,predictBeanType() 只会对当前未实例化的组件进行类型预测

总结

SmartInstantiationAwareBeanPostProcessor 中的 predictBeanType() 方法在 bean 的生命周期中被首次调用,且会被调用多次,因为后续 getBeanNamesForType() 方法还会执行且只要 getBeanNamesForType() 执行,predictBeanType() 就会被调用

生命周期接口解析之 InstantiationAwareBeanPostProcessor(一)

SmartInstantiationAwareBeanPostProcessor 执行后,下一个就是 InstantiationAwareBeanPostProcessor,继续追踪源码

// 刷新容器
public ClassPathXmlApplicationContext(
    String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
    throws BeansException {

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

来到熟悉的刷新容器十二大步

......
try {
    // Allows post-processing of the bean factory in context subclasses.
    postProcessBeanFactory(beanFactory);

    // Invoke factory processors registered as beans in the context.
    invokeBeanFactoryPostProcessors(beanFactory);

    // Register bean processors that intercept bean creation.
    registerBeanPostProcessors(beanFactory);

    // Initialize message source for this context.
    initMessageSource();

    // Initialize event multicaster for this context.
    initApplicationEventMulticaster();

    // Initialize other special beans in specific context subclasses.
    onRefresh();

    // Check for listener beans and register them.
    registerListeners();

    // 实例化所有剩余的非懒加载的单例(堆栈点)
    finishBeanFactoryInitialization(beanFactory);

    // Last step: publish corresponding event.
    finishRefresh();
}
......

这次的堆栈点停留到了 finishBeanFactoryInitialization() 处,继续追踪

// 实例化所有剩下的非懒加载的 bean
beanFactory.preInstantiateSingletons();

之后就是根据 bean 名称获取 bean 定义信息,对 bean 定义信息进行一系列判断,最后调用 getBean() 创建 bean 实例等逻辑,相关源码如下

// Trigger initialization of all non-lazy singleton beans...
// 遍历所有的 beanName
for (String beanName : beanNames) {
    // 通过 beanName 获取 bean定义信息
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    // 根据 bean 定义信息判断 bean 是否为抽象,单例且不为懒加载
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        // 判断是否为工厂 bean
        if (isFactoryBean(beanName)) {
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
                final 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 {
            // 获取 beean 实例
            getBean(beanName);
        }
    }
}

在 getBean() 的调用过程中,一定会在 getSingleton() 的 lambda 表达式中调用 createBean() 而 InstantiationAwareBeanPostProcessor 后置处理器起作用的关键逻辑也在 createBean() 中

@Override
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 {
        // 让 BeanPostProcessors 有机会返回一个代理而不是目标 bean 实例
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        // 如果上一步通过 InstantiationAwareBeanPostProcessor 返回了代理对象,则直接返回,不会执行下面断的 Spring 对象创建逻辑
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                        "BeanPostProcessor before instantiation of bean failed", ex);
    }

    try {
        // 上面没有通过 InstantiationAwareBeanPostProcessor 创建代理对象,则执行原本的创建对象逻辑
        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);
    }
}

跟踪 resolveBeforeInstantiation()

@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            // 目标类型不为空
            if (targetType != null) {
                // 在 bean 初始化前,应用 bean 后置处理器(堆栈点)
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    // 在 bean 初始化之后应用后置处理器
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

继续深入 applyBeanPostProcessorsBeforeInstantiation()

@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    // 遍历 bean 后置处理器,判断是否为 InstantiationAwareBeanPostProcessor 类型
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            // 如果是 InstantiationAwareBeanPostProcessor 类型的,就调用其 postProcessBeforeInstantiation() 方法
            // 该方法可以自定义的返回一个对象实例,这个对象实例由我们在方法中自定义创建而不由 spring 干预
            // 这也是 BeanPostProcesser 中,第二个执行的后置处理方法
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

以上,分析出了 BeanPostProcesser 系列中,第二个执行的后置处理方法,也就是 InstantiationAwareBeanPostProcessor 中的 postProcessBeforeInstantiation()

生命周期接口解析之 SmartInstantiationAwareBeanPostProcessor(二)

跟 SmartInstantiationAwareBeanPostProcessor 接口相关的后置处理已经是多次出现了,第一次通过调用 predictBeanType() 进行了类型预测,后续在调用 doGetBeanNamesForType() 方法时,predictBeanType() 也会继续调用

而这次,SmartInstantiationAwareBeanPostProcessor 中的 determineCandidateConstructors() 在 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation() 执行后,被调用,成为了 BeanPostProcesser 后置处理逻辑中,第三个执行的逻辑,下面对该逻辑的执行流程进行梳理

首先,构造容器实例,刷新工厂

public ClassPathXmlApplicationContext(
    String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
    throws BeansException {

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

执行工厂刷新的十二大步

/*
加载或刷新配置的持久表示,可能是 XML 文件、属性文件或关系数据库架构
由于这是一个启动方法,如果失败,它应该销毁已经创建的单例,以避免悬空资源。换句话说,在调用该方法后,要么全部实例化,要么根本不实例化

异常行为:
@throws BeansException 如果无法初始化 bean 工厂 
@throws IllegalStateException 如果已经初始化并且不支持多次刷新尝试
*/
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 准备此上下文以进行刷新
        prepareRefresh();

        // 告诉子类刷新内部 bean 工厂。
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 准备在此上下文中使用的 bean 工厂。
        prepareBeanFactory(beanFactory);

        try {
            // 允许在上下文子类中对 bean 工厂进行后处理。
            postProcessBeanFactory(beanFactory);

            // 调用在上下文中注册为 bean 的工厂处理器。
            invokeBeanFactoryPostProcessors(beanFactory);

            // 注册拦截 bean 创建的 bean 处理器。
            registerBeanPostProcessors(beanFactory);

            // 为此上下文初始化消息源。
            initMessageSource();

            // 为此上下文初始化事件多播器。
            initApplicationEventMulticaster();

            // 初始化特定上下文子类中的其他特殊 bean。
            onRefresh();

            // 检查侦听器 bean 并注册它们。
            registerListeners();

            // 实例化所有的单实例 bean(堆栈点)
            finishBeanFactoryInitialization(beanFactory);

            // 最后一步:发布相应的事件。
            finishRefresh();
        }
        ......

这次的堆栈点任然停留到了 finishBeanFactoryInitialization(),往后就是创建 bean 实例的过程,getBean() >>> doGetBean() >>> getSingleton() >>> lambad 表达式调用 createBean()

在 createBean() 中,又主要通过 doCreateBean() 来获取 bean 实例,doCreateBean() 中,继续调用 createBeanInstance(),第三个后置处理逻辑也在 createBeanInstance() 被执行

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 从 bean 定义信息中得到 bean 的类型
    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());
    }

    // 判断 bean 是否被定义为 bean 的实例提供者
    // 这相当于在 bean 的定义信息中设置了 Supplier 类型的实例,Supplier 实例能够提供自定义的 bean 实例而无需 spring 创建
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    // 判断是否使用工厂方法,通常指的就是在配置类中,被 @Bean 标识的方法
    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);
        }
    }

    // 使用构造器创建 bean 实例,在这之前,调用后置处理器逻辑,可以选择自定义使用哪个构造器(堆栈点)
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        // 如果在 bean 后置处理逻辑中我们使用返回了构造器,则会使用我们返回的构造器方式创建 bean 实例
        return autowireConstructor(beanName, mbd, ctors, args);
    }

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

    // 默认调用常规的无参构造函数
    return instantiateBean(beanName, mbd);
}

堆栈停留在了 determineConstructorsFromBeanPostProcessors() 处,其内部源码如下

@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
    throws BeansException {

    if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
        // 得到所有的 bean 后置处理器
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            // 找到 SmartInstantiationAwareBeanPostProcessor 类型的 bean 后置处理器
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                // 调用其中的 determineCandidateConstructors(),该方法自定义返回一个指定的构造器
                Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
                if (ctors != null) {
                    return ctors;
                }
            }
        }
    }
    return null;
}

以上就是 bean 后置处理的第三次执行,为 SmartInstantiationAwareBeanPostProcessor 中的 determineCandidateConstructors(),主要用于在 bean 调用构造器实例化之前,通过 determineCandidateConstructors() 来使用自定义的构造器创建 bean 实例

生命周期接口解析之 MergedBeanDefinitionPostProcessor(一)

下面进入 bean 生命周期过程中,bean 后置处理的第四次执行流程分析

前面的流程和上面 SmartInstantiationAwareBeanPostProcessor 第三次执行的流程过程一致,直到 doCreateBean() 中,第四次 bean 后置处理逻辑被执行,它是在 createBeanInstance() 调用,也就是 bean 实例化之后执行的

........
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
    instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
    mbd.resolvedTargetType = beanType;
}

// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
        try {
            // 应用合并的 Bean 定义后处理器
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                            "Post-processing of merged bean definition failed", ex);
        }
        mbd.postProcessed = true;
    }
}
......

跟踪 applyMergedBeanDefinitionPostProcessors()

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof MergedBeanDefinitionPostProcessor) {
            MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
            bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
        }
    }
}

还是一样的逻辑,遍历获取 bean 后置处理器,判断类型为 MergedBeanDefinitionPostProcessor,调用其中的 postProcessMergedBeanDefinition(),目的在于再次修改 bean 的定义信息

生命周期接口解析之 InstantiationAwareBeanPostProcessor(二)

bean 后置处理的第五次调用,继续来到了 InstantiationAwareBeanPostProcessor 中,调用的位置任然在 doCreateBean() 中,且紧接着上面的 MergedBeanDefinitionPostProcessor 调用,堆栈点位于 populateBean() 处,说明本次 bean 后置处理的调用发生在 populateBean() 内部,和 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);
    }
}

追踪堆栈点,部分源码如下

/*
在设置属性之前,让任何 InstantiationAwareBeanPostProcessors 有机会修改 bean 的状态。例如,这可用于支持字段注入样式。
*/
boolean continueWithPropertyPopulation = true;

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

遍历所有的 beam 后置处理,判断其中的 InstantiationAwareBeanPostProcessor,调用其 postProcessAfterInstantiation() 方法,完成 bean 后置处理逻辑的第五次调用,目的在于通过 postProcessAfterInstantiation() 在 bean 实例化之后,spring 属性赋值之前,可以自定义的对 bean 实例执行一些操作

需要注意的是,如果我们在 postProcessAfterInstantiation() 规定的返回值为 false,spring 自己的后续的属性赋值逻辑将不会执行,populateBean() 方法直接退出

生命周期接口解析之 InstantiationAwareBeanPostProcessor(三)

如果上面 postProcessAfterInstantiation 返回了 true,则会继续执行 InstantiationAwareBeanPostProcessor 中的 postProcessProperties() 方法,这是 bean 后置处理逻辑的第六次执行且紧接上面的 postProcessAfterInstantiation() 执行,部分源码如下

........
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
    if (pvs == null) {
        // 获取 xml 中 property 标签指定的 bean 属性值
        pvs = mbd.getPropertyValues();
    }
    // 遍历 bean 后置处理器
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        // 判断 InstantiationAwareBeanPostProcessor 类型
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // 调用 postProcessProperties() 方法
            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }
                pvsToUse = ibp.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) {
    // 将上面通过后置处理器处理后返回的 pvs 应用到 bean 实例中
    applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

本次调用的 bean 后置处理 postProcessProperties() 方法,主要作用在于:在工厂将给定的属性值应用于给定的 bean 之前对给定的属性值进行处理;其中,方法参数 PropertyValues 类型的 pvs 封装了所有的属性信息

@Autowired 的自动装配也发生于此,主要由 AutowiredAnnotationBeanPostProcessor 在其 postProcessProperties() 方法中实现,注意

@Autowired 自动装配在 postProcessProperties() 不是直接给 bean 实例的属性直接赋值,而是会返回一个 PropertyValues,这是属性键值对的集合,后续在 applyPropertyValues() 中才是对 bean 实例赋值的操作,而这个赋值操作,依靠的是 bean 实例被包装后的 org.springframework.beans.BeanWrapper 实现

生命周期接口解析之 BeanPostProcessor(一)

经过前面几次的调用,后置处理逻辑已经覆盖到了 bean 实例的创建到 bean 实例的属性赋值方面,在属性赋值结束后,紧接了执行了第七次的 bean 后置处理逻辑,直接来自于 BeanPostProcessor 中的 postProcessBeforeInitialization() 方法

该后置处理逻辑的执行,依然在 doCreateBean() 中,部分源码如下

.....
    // Initialize the bean instance.
    Object exposedObject = bean;
try {
    populateBean(beanName, mbd, instanceWrapper);
    // 初始化 bean 实例(堆栈点)
    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);
    }
}
.....

追踪 initializeBean()

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
            /*
            如果组件实现有以下接口
            BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
            则执行对应 Aware 实例属性的注入逻辑
            */
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            // 在初始化之前应用 Bean 后处理器(堆栈点)
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
            // 如果组件实现了 InitializingBean,则会在此处调用其 afterPropertiesSet() 方法
			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()) {
            // 在初始化后,应用 Bean 后处理器(堆栈点)
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

其中,还会执行 invokeInitMethods() 方法,凡是实现了 InitializingBean 接口或者指定了自定义的初始化方法的 bean,其中的初始化方法就在 invokeInitMethods() 逻辑中被调用,invokeInitMethods() 源码如下

/*
现在给一个 bean 一个反应的机会,它的所有属性都已设置,并有机会了解它拥有的 bean 工厂(这个对象)。这意味着检查 bean 是否实现了 InitializingBean 或定义了自定义的 init 方法,如果是,则调用其回调:afterPropertiesSet() 或者自定义回调方法
*/
protected void invokeInitMethods(String beanName, final 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 接口的 afterPropertiesSet() 方法
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    // 从 bean 定义信息中得到自定义的初始化方法相关信息
    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);
        }
    }
}

自定义方法的设置如下

/*
setInitMethodName("xxx")
指定自定义的初始化方法名称,例如在类中有一个方法名为 myInit(),
则通过 rootBeanDefinition.setInitMethodName(”myInit“);则可以设置该方法为自定义的初始化方法
*/
rootBeanDefinition.setInitMethodName("xxx");

或者通过 @Bean 注解的 initMethod 属性进行设置

最后执行 applyBeanPostProcessorsAfterInitialization() 方法,其源码如下

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

执行了 BeanPostProcessor 中的 postProcessBeforeInitialization() 方法,作用在于,即使当前 bean 已经实例化且属性被赋值,仍然可以通过该方法,返回一个自定义的 bean 实例,也就是说,在 bean 初始化的环节中,之前的 bean 又可能被替代或者改变。

之后,还会执行 applyBeanPostProcessorsAfterInitialization(),调用的是 BeanPostProcessor 中的 postProcessAfterInitialization() 方法,这两个方法,分别在 invokeInitMethods() 调用前后被调用,因此一个叫初始化之前(BeforeInitialization),一个叫初始化之后(AfterInitialization)。

以上流程都在 initializeBean() 方法中执行完毕,最终会返回一个 exposedObject 实例,这就是最终被创建成功的 bean 实例对象,部分源码如下

......
try {
    populateBean(beanName, mbd, instanceWrapper);
    exposedObject = initializeBean(beanName, exposedObject, mbd);
}
.....

spring bean 生命周期总结

以上的这些整个逻辑大部分都在 doCreateBean() 中被执行,doCreateBean() 实际上被 createBean() 调用,createBean 又在 getSingleton() 的 lambda 表达式中调用,而这一切,都只是因为在 DefaultListableBeanFactory 的 preInstantiateSingletons() 方法中,遍历 bean 的定义信息,获取 bean 实例时,调用的 getBean() 方法引起的;preInstantiateSingletons() 又是被 spring 容器创建时,刷新工厂的十二大步中的 finishBeanFactoryInitialization() 调用,最终,工厂完成刷新,spring 容器被创建,我们才可以直接使用其中的 bean 实例。

至此,spring 中,bean 创建的整个生命周期的执行流程就完毕了,对于 spring bean 的整个流程,大致上可分为

实例化,主要方法:createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

属性填充,主要方法:populateBean(beanName, mbd, instanceWrapper)

初始化,主要方法:initializeBean(beanName, exposedObject, mbd);

销毁,spring 容器关闭时,会调用销毁方法,该方法可以通过标注注解,实现接口,或者自定义来规定,可参考相关博客:https://cloud.tencent.com/developer/article/1730097

在这几个生命周期阶段中,各种后置处理器就穿插其间,影响 bean 的整个创建和初始化过程

spring 其他功能的实现,也是基于此生命周期来的,例如 spring 的事务,那就一定有一个事务相关的后置处理器,会检查方法是否标注了 @Transactional 注解,在处理器的后置处理逻辑中,进行一些事务的操作;又或者是 @Controller 注解,那也是在被标注了 @Controller 注解的组件在实例化时,通过执行生命周期中的某些环节的逻辑来实现客户端请求到指定目标方法的功能的。

流程图总结

补充

想要查看 spring 中注册了那些组件,可以直接给 RootBeanDefinition 的构造器打上断点

又或者是给刷新容器方法 refresh() 的最后一行打上断点来分析 spring 的整个流程


bean 初始化流程梳理

下面,对 bean 的初始化流程,从整体角度进行一个梳理。

spring bean 的初始化流程,发生在刷新工厂十二步的 finishBeanFactoryInitialization() 方法处,最终在 preInstantiateSingletons() 方法中被执行,源码如下

// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
    // 根据 bean 名称获取 bean 定义信息
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    // 判断是否为抽象类,是否为单实例,是否为懒加载
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         // 判断是否为工厂 bean
        if (isFactoryBean(beanName)) {
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
                final 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);
        }
    }
}

这里先研究工厂 bean 的初始化流程,在 bean 的定义信息满足了单实例,非抽象类,非懒加载的条件后,紧接着就是判断是否工厂 bean 的流程,追踪源码如下

@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);
    // 先尝试获取以下 bean 的实例
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null) {
        // 如果 bean 实例已经被创建,则使用 bean 的实例判断是否为工厂 bean
        return (beanInstance instanceof FactoryBean);
    }
    // No singleton instance found -> check bean definition.
    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
        // No bean definition found in this factory -> delegate to parent.
        return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
    }
    // 通过 bean 定义信息来判断是否为工厂 bean
    return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}

isFactoryBean() 源码如下

protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
    // 直接通过 bean 定义信息中的 isFactoryBean 属性来判断是否为工厂 bean,这是在最初加载资源时就封装在 bean 定义信息中的
    Boolean result = mbd.isFactoryBean;
    if (result == null) {
        // 如果 isFactoryBean 为 null,则先通过 predictBeanType() 来获取 bean 的类型
        Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
        // 只要 beanType 也为 null 或者 beanType 的类型不是 FactoryBean,那么对 bean 定义信息中的 isFactoryBean 赋值
        // 最终返回
        result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
        mbd.isFactoryBean = result;
    }
    return result;
}

继续回到 preInstantiateSingletons() 中

// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
    // 根据 bean 名称获取 bean 定义信息
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    // 判断是否为抽象类,是否为单实例,是否为懒加载
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         // 判断是否为工厂 bean
        if (isFactoryBean(beanName)) {
            // 是一个工厂 bean,通过 getBean() 得到工厂 bean 实例
            // 工厂 bean 的名字前面会加上一个 &(FACTORY_BEAN_PREFIX) 符号作为标识
            // 且通过该 beanName 从容器中获取 bean 实例
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
                final FactoryBean<?> factory = (FactoryBean<?>) bean;
                boolean isEagerInit;
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                    isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                                                ((SmartFactoryBean<?>) factory)::isEagerInit,
                                                                getAccessControlContext());
                }
                else {
                    // 工厂 bean 可以实现 SmartFactoryBean 接口,在 isEagerInit() 指定提前加载工厂 bean
                    isEagerInit = (factory instanceof SmartFactoryBean &&
                                   ((SmartFactoryBean<?>) factory).isEagerInit());
                }
                if (isEagerInit) {
                    getBean(beanName);
                }
            }
        }
        else {
            getBean(beanName);
        }
    }
}

工厂 bean 被创建后,其 getObject() 方法并不会立即执行,而是从容器中获取 getObject() 方法对应返回值类型的 bean 实例时,调用 getObject() 创建 bean 实例,这也是 FactoryBean 的作用;当我们从容器中获取 bean 实例,调用的是 getBean(),此时 FactoryBean 返回对应实例的 getObject() 逻辑会在 getBean() 中执行;下面,通过 debug 调试源码来追踪其完整流程

首先,从 spring 容器中获取一个 Person.class 类型的实例,该实例通过 FactoryBean 来得到

Person bean = applicationContext.getBean(Person.class);

追踪 getBean() 源码

@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
    assertBeanFactoryActive();
    return getBeanFactory().getBean(requiredType);
}

从工厂中获取 bean

追踪源码

@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
    return getBean(requiredType, (Object[]) null);
}

通过类型从工厂中获取 bean 实例

@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
    Assert.notNull(requiredType, "Required type must not be null");
    // 解析 bean
    Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
    if (resolved == null) {
        throw new NoSuchBeanDefinitionException(requiredType);
    }
    return (T) resolved;
}

追踪 resolveBean()

private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
    // 先尝试解析出一个 NamedBeanHolder,包含 beanName + bean 实例
    NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
    if (namedBean != null) {
        // 解析出了 NamedBeanHolder 直接返回
        return namedBean.getBeanInstance();
    }
    BeanFactory parent = getParentBeanFactory();
    if (parent instanceof DefaultListableBeanFactory) {
        return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);
    }
    else if (parent != null) {
        ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
        if (args != null) {
            return parentProvider.getObject(args);
        }
        else {
            return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
        }
    }
    return null;
}

追踪 resolveNamedBean(requiredType, args, nonUniqueAsNull),部分源码如下

private <T> NamedBeanHolder<T> resolveNamedBean(
			ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {

		Assert.notNull(requiredType, "Required type must not be null");
		String[] candidateNames = getBeanNamesForType(requiredType);
		.....

又来到了 getBeanNamesForType() 根据类型获取 beanName 的环节,在在这里面会遍历得到每一个 bean 定义信息;此时若存在工厂 bean,则会判断工厂 bean 类中,getObject() 方法的返回值类型,该类型又由工厂 bean 类中的 getObjectType() 方法获取到,将其 beanName 加上 & 前缀作为返回值;如果是工厂 bean,在 getBeanNamesForType() 方法中,会调用 isTypeMatch() 方法来判断是否符合方法参数中的 requiredType 类型,isTypeMatch() 部分源码如下

protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit)
    throws NoSuchBeanDefinitionException {

    String beanName = transformedBeanName(name);
    boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name);

    // Check manually registered singletons.
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
        // 如果是一个工厂 bean
        if (beanInstance instanceof FactoryBean) {
            if (!isFactoryDereference) {
                // 获取工厂 bean 创建的实例的类型,此处就会调用工厂 bean 的 getObjectType() 方法
                Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
                // 确定 typeToMatch(目标类型)是否可以从 type(工厂 bean 返回的类型)中得到
                return (type != null && typeToMatch.isAssignableFrom(type));
            }
            else {
                return typeToMatch.isInstance(beanInstance);
            }
        }
        .......

如果工厂 bean 的返回类型符合目标 bean 的类型,那么最终 isTypeMatch() 会返回 true,这也代表 getBeanNamesForType() 方法的返回值中,会有对应的工厂 bean 的 beanName【工厂 bean 前缀(&) + beanName】

退回到 resolveNamedBean() 方法中

private <T> NamedBeanHolder<T> resolveNamedBean(
			ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {

		Assert.notNull(requiredType, "Required type must not be null");
		String[] candidateNames = getBeanNamesForType(requiredType);
.....
    // 上述 getBeanNamesForType() 操作返回了工厂 bean 的名称,代表该工厂 bean 可以返回类型为指定类型的 bean 实例
    if (candidateNames.length == 1) {
        String beanName = candidateNames[0];
        // 加载工厂 bean 的实例返回
        return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args));
    }
.....

调用 getBean() 方法

public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
    throws BeansException {

    return doGetBean(name, requiredType, args, false);
}

继续追踪

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                          @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // 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 + "'");
            }
        }
        //堆栈点
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    ......

继续追踪

// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
/*
现在我们有了 bean 实例,它可能是普通 bean 或 FactoryBean。如果它是一个 FactoryBean,我们就用它来创建一个 bean 实例,除非调用者实际上想要一个对工厂的引用。
*/
if (!(beanInstance instanceof FactoryBean)) {
    return beanInstance;
}

Object object = null;
if (mbd != null) {
    mbd.isFactoryBean = true;
}
else {
    // 获得工厂 bean 的缓存对象
    object = getCachedObjectForFactoryBean(beanName);
}
// 缓存为 null
if (object == null) {
    // Return bean instance from factory.
    FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
    // Caches object obtained from FactoryBean if it is a singleton.
    if (mbd == null && containsBeanDefinition(beanName)) {
        mbd = getMergedLocalBeanDefinition(beanName);
    }
    boolean synthetic = (mbd != null && mbd.isSynthetic());
    // 从工厂 bean 中获取目标 bean 实例
    object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}

追踪 getObjectFromFactoryBean(),部分源码如下

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    if (factory.isSingleton() && containsSingleton(beanName)) {
        synchronized (getSingletonMutex()) {
            // 先从工厂 bean 的缓存中获取
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
                // 缓存中没有,调用工厂方法获取
                object = doGetObjectFromFactoryBean(factory, beanName);
                // Only post-process and store if not put there already during getObject() call above
                // (e.g. because of circular reference processing triggered by custom getBean calls)
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
.......
    	// 首次调用工厂方法,将目标 bean 实例放入工厂 bean 的缓存中,下次直接获取;所以工厂 bean 也是单实例的
    	if (containsSingleton(beanName)) {
							this.factoryBeanObjectCache.put(beanName, object);
		}

追踪 doGetObjectFromFactoryBean(),部分源码如下

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
    throws BeanCreationException {

    Object object;
    try {
        if (System.getSecurityManager() != null) {
            AccessControlContext acc = getAccessControlContext();
            try {
                object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            // 此处就调用了工厂 bean 中的 getObject() 方法,返回了目标 bean 实例
            object = factory.getObject();
        }
    }

以上,整个工厂 bean 获取实例的大致流程就结束了。

工厂 bean 的流程完成后,剩下的就是普通的单实例 bean 的初始化流程;经过 refresh() >>> finishBeanFactoryInitialization() >>> beanFactory.preInstantiateSingletons() 又来到了下面熟悉的流程

@Override
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    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()) {
            // 工厂 bean 的执行逻辑
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    final FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                                                    ((SmartFactoryBean<?>) factory)::isEagerInit,
                                                                    getAccessControlContext());
                    }
                    else {
                        // 工厂 bean 提前加载
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                       ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            }
            else {
                // 普通 bean 的初始化逻辑
                getBean(beanName);
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

getBean() 底层继续调用了 doGetBean(),其源码如下

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                          @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // 快速的检测单例池中是否有对应的实例
    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 + "'");
            }
        }
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    else {
        // 首次创建,肯定会执行 else 中的逻辑
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 得到一个父级 bean 工厂,spring 整合 mvc 时,spring 容器就存在父子关系,这里是纯 spring,返回为 null
        // 若有父容器,则尝试从父容器中获取组件实例
        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) {
            // 标记 bean 已经被创建
            markBeanAsCreated(beanName);
        }

        try {
            // 得到组件定义信息
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // 获取目标组件依赖了那些组件
            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);
                    }
                }
            }

            // 创建 bean 单实例
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        // Explicitly remove instance from singleton cache: It might have been put there
                        // eagerly by the creation process, to allow for circular reference resolution.
                        // Also remove any beans that received a temporary reference to the bean.
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            // 创建 bean 的多实例
            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);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            // 单实例和多实例都无法区分,则直接获取 bean 的 scope 属性来进行后续处理
            else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                                                    "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                                    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                                    ex);
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // 检查所需类型是否与实际 bean 实例的类型匹配
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
        }
        catch (TypeMismatchException ex) {
            if (logger.isTraceEnabled()) {
                logger.trace("Failed to convert bean '" + name + "' to required type '" +
                             ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

其中,最开始调用的 getSingleton() 底层继续调用了一个双参的 getSingleton(beanName, true),该方法的第二个布尔参数代表【是否允许早期引用】,该方法源码如下

/*
返回在给定名称下注册的(原始)单例对象。检查已经实例化的单例,并允许对当前创建的单例进行早期引用(解决循环引用)。
在当前方法中,就涉及到了 spring 循环依赖的解决,也就是三级缓存
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 检测单例缓存池获取对应 bean 实例
    Object singletonObject = this.singletonObjects.get(beanName); //一级缓存 singletonObjects
    // 第一次获取肯定没有对应的 bean 实例,如果返回值为 null 且当前 bean 正在创建【isSingletonCurrentlyInCreation()】
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);// 二级缓存 earlySingletonObjects
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();// 三级缓存 singletonFactory
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

按照正常流程,就会执行 lambda 表达式形式的单实例 bean 创建流程,首先,外部的 getSingleton() 调用

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
            // 先检测单例池中是否有对应的实例
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
                // 单实例创建之前执行
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
                    // 这里相当于 lambda 的执行,因为 getSingleton() 的 singletonFactory 参数通过 lambda 表达式的形式传入,这里调用到了 singletonFactory
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

如果单例池中没有单实例缓存,则会创建单实例,首先就进入 beforeSingletonCreation()

protected void beforeSingletonCreation(String beanName) {
 // 如果当前要创建的 bean 不在 inCreationCheckExclusions 中且往 singletonsCurrentlyInCreation 中添加失败
 // 则抛出异常
 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
     throw new BeanCurrentlyInCreationException(beanName);
 }
}

其中,singletonsCurrentlyInCreation 会把当前要创建的对象名称保存起来,这个很关键

最后,getSingleton() 会调用 createBean() ,这其中经过 bean 的完整生命周期(实例化,后置处理器,属性赋值,初始化等);最终创建出 bean 对象实例。

bean 初始化的流程图总结如下


spring 容器刷新流程梳理

正常情况下,使用 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);创建一个 spring 容器,之后便是容器刷新的十二大步

首先是手动通过 new 的方式创建了 spring 容器

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    // 调用空参构造
    this();
    // 注册主配置类,也就是 new AnnotationConfigApplicationContext(Config.class); 时传入的配置类
    register(componentClasses);
    // 刷新工厂十二大步
    refresh();
}

首先看 this() 空参调用环节

public AnnotationConfigApplicationContext() {
    // 创建读取器,传入 bean 定义信息的注册中心
    this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

AnnotatedBeanDefinitionReader 的构造器底层调用的时另一个重写的构造器,如下

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    // 注册注解配置处理器
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

追踪 registerAnnotationConfigProcessors()

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
    BeanDefinitionRegistry registry, @Nullable Object source) {

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

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

    /*
    判断注册中心中有没有指定的组件,没有的话直接 new 出来
    这里注册的就是 spring 系统中的底层组件
    */
    
    /* CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    处理配置类的组件
    */
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    /*
    AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    自动装配的组件
    */
    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));
    }
    
    /*
    COMMON_ANNOTATION_PROCESSOR_BEAN_NAME:org.springframework.context.annotation.internalCommonAnnotationProcessor
    jsr250 的组件,用于统一规范 JavaEE 的注解使用,不同框架或组件间重复(或冗余)的注解。
    普通的 jsr250 规范的注解
    */
    // 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));
    }

    /*
    PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME:org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
    */
    // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                                                AnnotationConfigUtils.class.getClassLoader()));
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
        }
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    /*
    EVENT_LISTENER_PROCESSOR_BEAN_NAME:org.springframework.context.event.internalEventListenerProcessor
    */
    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));
    }

    /*
   EVENT_LISTENER_FACTORY_BEAN_NAME:org.springframework.context.event.internalEventListenerFactory
    */
    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;
}

以上是创建读取器的过程,主要是注册一些底层的核心组件 bean 定义信息

紧接着,又创建了一个扫描器 this.scanner = new ClassPathBeanDefinitionScanner(this);,用于准备环境变量等信息

以上是空参构造器 this() 的执行流程,接着便是 register(componentClasses) 的流程

先跟踪第一次 register(),参数直接传入了主配置类,使用 this() 中构建好的 reader 读取主配置类

@Override
public void register(Class<?>... componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    // 注册所有的主配置类
    this.reader.register(componentClasses);
}

继续跟踪,底层调用的是 doRegisterBean()

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

    // 将著配置类也封装为一个 bean 定义信息
    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));

    // processCommonDefinitionAnnotations:处理主配置类,检查出主配置类中标注的核心注解,封装到主配置类的定义信息中
    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);
}

以上,register() 流程就结束了

下面进入容器刷新的十二大步

/*
加载或刷新配置的持久表示,可能是 XML 文件、属性文件或关系数据库架构
由于这是一个启动方法,如果失败,它应该销毁已经创建的单例,以避免悬空资源。换句话说,在调用该方法后,要么全部实例化,要么根本不实例化

异常行为:
@throws BeansException 如果无法初始化 bean 工厂 
@throws IllegalStateException 如果已经初始化并且不支持多次刷新尝试
*/
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 准备上下文环境
        prepareRefresh();

        // 工厂创建,BeanFactory 第一次创建时,有 xml 解析逻辑
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 给容器中注册了环境信息方便后续自动装配,放了一些后置处理器
        prepareBeanFactory(beanFactory);

        try {
            // 留给子类的模板方法,允许子类对工厂执行一些逻辑
            postProcessBeanFactory(beanFactory);

            // 调用在上下文中注册为 bean 的工厂后置处理器:BeanFactoryPortProcesser
            invokeBeanFactoryPostProcessors(beanFactory);

            // 注册所有的 bean 后置处理器
            registerBeanPostProcessors(beanFactory);

            // 初始化国际化功能
            initMessageSource();

            // 初始化事件多播功能
            initApplicationEventMulticaster();

            // 初始化特定上下文子类中的其他特殊 bean。
            onRefresh();

            // 注册监听器 ApplicationListener
            registerListeners();

            // 实例化所有的单实例 bean,bean 后置处理器逻辑也在这里面执行
            finishBeanFactoryInitialization(beanFactory);

            // 最后一步:发布相应的事件。
            finishRefresh();
        }
        ......

最终,spring 容器刷新的详细流程图总结如下


循环依赖

循环依赖指的是,A 组件中依赖了 B 组件,同时 B 组件又依赖了 A 组件,如下

@Component
public class B {
    private A a;

    public B() {
        System.out.println("B 构造方法 ...");
    }

    @Autowired
    public void setA(A a) {
        this.a = a;
    }
}
@Component
public class A {
    private B b;

    public A(){
        System.out.println("A 构造方法 ...");
    }

    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

又或者是组件自己依赖自己

@Component
public class Self {

    private Self self;

    public Self() {
        System.out.println("Self 构造方法 ...");
    }

    @Autowired
    public void setSelf(Self self) {
        this.self = self;
    }
}

下面,通过 A 依赖 B 的方式来剖析 spring 应对循环依赖的过程,通过 debug 发现 A 组件先进入实例化的过程,直接通过 getBean() 获取 A 实例,通过 getBean() 又继续来到 doGetBean(),首先检查缓存中是否有已经手动实例化的单实例

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// 快速的检查缓存中是否有手动注册的单实例
		Object sharedInstance = getSingleton(beanName);
    .... 

深入 getSingleton() 方法

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    /*
    先检查单例池,此时单例池中肯定没有 A 实例
    */
    Object singletonObject = this.singletonObjects.get(beanName);
    /*
    单例池中没有,继续检查是否正在创建中 isSingletonCurrentlyInCreation(beanName)
    底层实际上是通过 singletonsCurrentlyInCreation.contains(beanName); 检查该组件名是否
    在 singletonsCurrentlyInCreation 集合中来判断的
    */
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

以上如果单例池中没有且不是正在创建中,则会正常执行 getSingleton() 逻辑,在这其中,又会第二次检查单例池中是否有 A 组件

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        .....

此时单例池中依旧没有 A 组件的实例,继续执行 A 组件创建逻辑,而在 A 创建之前,会执行beforeSingletonCreation(beanName);如下

protected void beforeSingletonCreation(String beanName) {
    // 将当前正在创建的组件名称放入 singletonsCurrentlyInCreation 集合中,代表组件正在创建,也就是上面 isSingletonCurrentlyInCreation 所使用的集合
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
}

之后又继续执行组件实例化的逻辑,来到 createBean() 中,调用一系列的后置处理器,然后来到真正创建实例的地方

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

至此,A 组件的实例创建完成,组件的属性赋值还没有完成;接下来,在 doCreateBean() 方法中的属性赋值操作populateBean()执行之前,会先执行如下逻辑

/*
快速地缓存单例,以便在 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));
}

深入addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));逻辑

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    synchronized (this.singletonObjects) {
        // 当工厂中没有指定组件时
        if (!this.singletonObjects.containsKey(beanName)) {
            /*
            往 singletonFactories 中,按照 beanName 放入一个 singletonFactory
            当前方法参数中的 singletonFactory 在方法调用处,通过 lambda 表达式形式传入
            */
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}

lambda 表达式的具体逻辑如下

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
 Object exposedObject = bean;
 // 判断是否有 SmartInstantiationAwareBeanPostProcessor 后置处理器
 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
     for (BeanPostProcessor bp : getBeanPostProcessors()) {
         /*
         如果有的话,通过后置处理器的 getEarlyBeanReference() 方法返回实例
         */
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
             SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
             exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
         }
     }
 }
 // 在没有后置处理器的情况下,返回默认的 bean 实例
 return exposedObject;
}

以上 lambda 逻辑后续都会在通过 singletonFactories 获取 bean 实例时被调用

继续执行,来到 A 组件的赋值逻辑,这里面,针对循环依赖的情况,A 需要将 B 组件的实例注入到自己的属性中;深入 populateBean() 部分关键逻辑

.....
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
    if (pvs == null) {
        pvs = mbd.getPropertyValues();
    }
	// 因为循环依赖的属性是通过 @Autowire 自动注入的,因此需要关注 AutowiredAnnotationBeanPostProcessor 的调用
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }
                pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    return;
                }
            }
            pvs = pvsToUse;
        }
    }
}
....

AutowiredAnnotationBeanPostProcessor 后置处理器的 postProcessProperties() 中,执行以下逻辑

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    	// 找到所有需要自动注入的元数据,在这里就会感知到需要自动装配的属性,包括循环依赖的属性
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
            // 执行属性注入的逻辑
			metadata.inject(bean, beanName, pvs);
		}
		catch (BeanCreationException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}

对于 bean 属性的注入,通过 injec() 最终会调用到如下逻辑

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
    throws BeansException {
    return beanFactory.getBean(beanName);
}

依旧会通过 getBean() 来获取属性注入需要的实例,此时 A 组件依赖的 B 组件也进入了实例的创建流程且创建流程和 A 组件一致,因为 B 目前来说也是第一次创建,直到 B 组件的 populateBean() 执行时,情况发生了一些微妙的变化;因为 B 组件是依赖了 A 组件的,这一点在 AutowiredAnnotationBeanPostProcessor 的 postProcessProperties() 会被 findAutowiringMetadata() 解析出来,接下来,B 组件的属性元数据 InjectionMetadata metadata 开始执行 inject(bean, beanName, pvs) 注入属性;这其中就又会执行 getBean() 来获取 A 组件,前面的流程依然一样 getBean() > doGetBean(),注意,在 doGetBean() 中依然会先执行Object sharedInstance = getSingleton(beanName);检查工厂中是否有属性对应的 bean 实例,参照源码

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // A 组件还没有创建完成,singletonObjects 没有,返回 null 
    Object singletonObject = this.singletonObjects.get(beanName);
    /*
    单例池返回 null 且 A 组件在创建时,将自己的 beanName 放入了 singletonsCurrentlyInCreation 集合中,if 条件满足
    否则说明单例池中有对应实例了,直接返回即可
    
    这里使用了双端检查锁机制:
    首先在外层进行一次判断,不加锁,保证多线程执行下的效率
    */
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
       /*
       因为这里需要从缓存集合中获取数据,为了保证线程安全(主要是为了保证单实例),使用 singletonObjects 加锁
       因为存在线程虚假唤醒的问题,当多个线程并发获取实例时,同一批次的线程都判断了 singletonObject 为 null,若某个线程最先将 singletonObject 赋值,此时的 singletonObject 已经不为 null 了,但是后面的同批次最初判断 singletonObject 为 null 的线程却不知道,如果不进行第二次 null 判断,singletonObject 的单实例特性必定会被其余线程的重复赋值所破坏
       */
        synchronized (this.singletonObjects) {
            // 从缓存 earlySingletonObjects 中获取实例
            singletonObject = this.earlySingletonObjects.get(beanName);
            /*
            再次判断是否为 null,防止重复获取实例,破坏了单实例原则
            allowEarlyReference:允许早期参考
            */
            if (singletonObject == null && allowEarlyReference) {
                /*
                从 singletonFactories 中获取 A 组件的单例工厂,注意,A 组件在之前创建时,通过 addSingletonFactory() 方法已经将自己放入了 singletonFactories 中,这里是可以获到 A 组件的
                */ 
                // 从 singletonFactories 中得到 singletonFactory
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    // 使用 singletonFactory 得到 A 组件
                    singletonObject = singletonFactory.getObject();
                    /*
                    将 A 组件放入 earlySingletonObjects 中,紧接着又将 A 的单例工厂从 singletonFactories 中删除,这相当于是将 A 组件从所谓的三级缓存提升到了二级缓存
                    */
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    // 最终返回 A 组件
    return singletonObject;
}

到此,B 得了 A 组件,B 的属性赋值结束,后续就执行 B 组件的初始化逻辑,注意,此时 A 组件仍然停留在属性赋值阶段,它需要等 B 组件创建完成,B 的初始化逻辑完成后,B 组件的创建也就完成了,B 创建完成之后,继续执行初始化逻辑,然后又会进入如下逻辑

.....
// 早期单实例暴露
if (earlySingletonExposure) {
    /*
    getSingleton(beanName, false)
    继续进入三级缓存双检锁的逻辑,只不过这次的的参数2为:false,不允许早期参考(从三级缓存中获取)
    而此时的 B 组件是在三级缓存中的且又不允许早期参考,那么 getSingleton(beanName, false) 一定返回的是 null
    那么当前的 doCreateBean() 方法就会正常返回 bean 实例而不进行其他操作
    */
    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 " +
                                                           "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
            }
        }
    }
}
.....

之后,在外部的 doCreateBean() 的调用者,getSingleton() 方法的 finally 块中,还会执行一段关键逻辑,如下

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException(beanName,
                                                          "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                                                          "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // Has the singleton object implicitly appeared in the meantime ->
                // if yes, proceed with it since the exception indicates that state.
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    throw ex;
                }
            }
            catch (BeanCreationException ex) {
                if (recordSuppressedExceptions) {
                    for (Exception suppressedException : this.suppressedExceptions) {
                        ex.addRelatedCause(suppressedException);
                    }
                }
                throw ex;
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                // 关键逻辑
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                // 添加 B 组件实例
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

深入 afterSingletonCreation(beanName);

protected void afterSingletonCreation(String beanName) {
    // 将 B 组件从当前正在创建的 singletonsCurrentlyInCreation 缓存中删除
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}

深入 addSingleton(beanName, singletonObject)

protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        /*
        1.添加 B 组件到单例池 singletonObjects(一级缓存)中
        2.从singletonFactories(三级缓存)中删除 B 组件
        3.从earlySingletonObjects(二级缓存)中删除 B 组件
        相当于将 B 组件提升到了一级缓存中,因为 B 组件目前实际上已经创建完成且属性注入成功了
        */ 
        this.singletonObjects.put(beanName, singletonObject);
        this.singletonFactories.remove(beanName);
        this.earlySingletonObjects.remove(beanName);
        // 保存已注册的单例,包含按注册顺序排列的 bean 名称。
        this.registeredSingletons.add(beanName);
    }
}

至此,B 组件创建完成,提升到了一级缓存中,而 B 组件循环依赖的 A 组件目前还在二级缓存中;我们来梳理一下当前 A,B 组件在三级缓存中的变动情况:

最初,A 组件刚刚创建完实例时,作为一个早期单实例,通过 addSingletonFactory() 被放入了三级缓存 singletonFactories 中

接着 A 组件在注入属性时,触发了 B 组件的实例化创建和属性注入,B 组件的早期单实例也被放入了三级缓存中

之后 B 组件的属性注入通过三级缓存得到了 A 组件没有注入属性的早期单实例,然后将 A 组件由三级缓存提升到了二级缓存

此时 B 组件实例化,属性注入,初始化的逻辑全部完成,作为一个合格的单实例,B 组件被直接放入一级缓存的单例池中(singletonObjects)同时从三级缓存和二级缓存中移除,但实际上当前整个流程 B 组件并没有进入过二级缓存,只是执行了一个移除操作

目前,A 组件还在属性注入阶段,当 B 组件完全创建成功后,A 的属性注入会继续执行,此时 B 已经在一级缓存的单例池中存在了,A 在属性注入时调用的 getBean() 就直接可以从容器中得到 B 单实例,完成属性的注入,接着又是 A 的初始化逻辑执行,初始化之后又来到了早期单实例暴露逻辑,此时的 A 还在二级缓存中,那么双检锁的 getSingleton() 就能够在二级缓存中获取到 A 组件。

最终 A 组件也创建完成,依然会执行afterSingletonCreation()addSingleton()两个逻辑,将 A 从正在创建的缓存集合中移除,从二三级缓存中移除,将 A 组件放入一级缓存中。

需要注意的是,以上的整个所有流程,实际上我们实在获取 A 组件,目前 A 组件也获取完成了;B 组件虽然在 A 组件的获取过程中被完整创建了,但实际上顶层的真正获取 B 组件的逻辑并没有调用,当preInstantiateSingletons() 中遍历 bean 定义信息准备获取 B 组件时,才算是真正获取 B 组件,而此时 B 组件已经在一级缓存中了,直接 getBean() 就能从单例池中得到。

但实际上,就算没有三级缓存,只有二级,甚至是一级都能完成整个循环依赖的解决,因为三级缓存无非就是说将半成品的 bean 实例和完整的 bean 实例进行一个区分;就算直接使用一级缓存,通过规定一些 key 的特定标识来区分半成品和完全品的 bean 实例,也能达到同样的效果。

循环依赖流程图总结如下


spring aop

AOP(Aspect OrientedProgramming):面向切面编程,是 Spring 框架中的一个重要内容。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

为什么使用 aop

面向对象编程(OOP)的好处是显而易见的,缺点也同样明显。当需要为多个不具有继承关系的对象添加一个公共的方法的时候,例如日志记录、性能监控等,如果采用面向对象编程的方法,需要在每个对象里面都添加相同的方法,这样就产生了较大的重复工作量和大量的重复代码,不利于维护。面向切面编程(AOP)是面向对象编程的补充,简单来说就是统一处理某一“切面”的问题的编程思想。如果使用AOP的方式进行日志的记录和处理,所有的日志代码都集中于一处,不需要再每个方法里面都去添加,极大减少了重复代码。

aop 的使用简单高效,但是对其内部执行原理的掌握仍然具备一定的必要性,下面针对 spring aop 的源码进行分析

首先准备前置环境,在 spring boot 环境下,导入 aop 的 starter

<!--aop 切面-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

配置类中开启 spring aop

@EnableAspectJAutoProxy // 开启基于注解的 spring aop
@Configuration
@ComponentScan(basePackages = "com.dhj.demo")
public class Config {
}

准备业务类

@Component  //切面存在的话就会返回代理对象
public class HelloService {

    public HelloService() {
        System.out.println("....");
    }

    public String sayHello(String name) {
        String result = "你好:" + name;
        System.out.println(result);
        int length = name.length();
        return result + "---" + length;
    }
}

准备 aop 切面

@Component  //切面也是容器中的组件
@Aspect //标识该类为一个切面
public class LogAspect {

    public LogAspect() {
        System.out.println("LogAspect 构造方法...");
    }

    //前置通知  增强方法/增强器
    @Before("execution(* com.dhj.demo.aop.HelloService.sayHello(..))")
    public void logStart(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        System.out.println("前置通知:logStart()==>" + name + "....【args: " + Arrays.asList(joinPoint.getArgs()) + "】");
    }

    //返回通知
    @AfterReturning(value = "execution(* com.dhj.demo.aop.HelloService.sayHello(..))", returning = "result")
    public void logReturn(JoinPoint joinPoint, Object result) {
        String name = joinPoint.getSignature().getName();
        System.out.println("返回通知:logReturn()==>" + name + "....【args: " + Arrays.asList(joinPoint.getArgs()) + "】【result: " + result + "】");
    }

    //后置通知
    @After("execution(* com.dhj.demo.aop.HelloService.sayHello(..))")
    public void logEnd(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        System.out.println("后置通知:logEnd()==>" + name + "....【args: " + Arrays.asList(joinPoint.getArgs()) + "】");
    }


    //异常
    @AfterThrowing(value = "execution(* com.dhj.demo.aop.HelloService.sayHello(..))", throwing = "e")
    public void logError(JoinPoint joinPoint, Exception e) {
        String name = joinPoint.getSignature().getName();
        System.out.println("异常通知:logError()==>" + name + "....【args: " + Arrays.asList(joinPoint.getArgs()) + "】【exception: " + e + "】");
    }
}

要分析 aop 的实现原理,需要明确两点

向 spring 容器中放入了那些组件

这些组件干了什么事情

因为要使用 aop 就一定需要@EnableAspectJAutoProxy来开启 aop 功能,那么就可以直接从@EnableAspectJAutoProxy注解入手,其源码如下

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
	 * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
	 * Off by default, i.e. no guarantees that {@code AopContext} access will work.
	 * @since 4.3.1
	 */
	boolean exposeProxy() default false;

}

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);处打上断点,开启 debug 从全局角度分析@EnableAspectJAutoProxy注解的执行逻辑

首先,创建 spring 容器,在十二大步的invokeBeanFactoryPostProcessors(beanFactory);中通过org.springframework.context.annotation.ConfigurationClassPostProcessor加载解析配置类,内部调用processConfigBeanDefinitions(registry);在这其中会解析配置类;通过@EnableAspectJAutoProxy注解的源码可以知道,它通过@Import往容器中导入了一个组件:@Import(AspectJAutoProxyRegistrar.class),那么在解析配置类时,就会解析到@EnableAspectJAutoProxy中的@Import注解,解析@Import的关键源码如下

// 解析 @Import 注解
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());

最终解析到@EnableAspectJAutoProxy@Import注解的Class参数为org.springframework.context.annotation.AspectJAutoProxyRegistrar,该类实现了ImportBeanDefinitionRegistrar且重写了其中的registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)方法,该方法会向BeanDefinitionRegistry中注册 bean 定义信息,AspectJAutoProxyRegistrar 源码如下

import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

}

通过AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);注册 bean 定义信息,追踪该方法,有如下源码

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
    BeanDefinitionRegistry registry, @Nullable Object source) {

    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

其中,AnnotationAwareAspectJAutoProxyCreator.class便是最终要注册 bean 定义信息的 class 类型,检查该类的类图,如下

发现AnnotationAwareAspectJAutoProxyCreator实际上是一个BeanPostProcesser后置处理器,那么整个 aop 功能的实现就是依靠该后置处理器在 bean 创建时完成的。

接下来,就详细分析AnnotationAwareAspectJAutoProxyCreator在 aop 过程中的执行逻辑,首先依旧是创建 spring 容器实例,进入刷新容器十二大步,因为AnnotationAwareAspectJAutoProxyCreator是一个后置处理器,因此其具体逻辑的执行在容器刷新十二大步中的registerBeanPostProcessors(beanFactory);中;

之后便会获取后置处理器的实例,进入后置处理的getBean()流程:beanFactory.getBean(ppName, BeanPostProcessor.class);

因为AnnotationAwareAspectJAutoProxyCreator实现了BeanFactoryAware接口,则在其初始化时会调用invokeAwareMethods(),根据其实现的Aware接口类型来调用对应的接口方法,这里调用的是((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);,相关源码如下

@Override
public void setBeanFactory(BeanFactory beanFactory) {
    // 为其父类的 beanFactory 属性设置 BeanFactory 实例 
    super.setBeanFactory(beanFactory);
    if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
        throw new IllegalArgumentException(
            "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
    }
    // 调用子类中的 initBeanFactory()
    initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}

子类中的initBeanFactory()实现如下

@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 先执行父类中的 initBeanFactory() 方法
    super.initBeanFactory(beanFactory);
    if (this.aspectJAdvisorFactory == null) {
        // 为本类属性 aspectJAdvisorFactory 赋值一个 ReflectiveAspectJAdvisorFactory 实例(反射方式的 AspectJAdvisor 增强器工厂)
        this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
    }
    // 创建一个 aspectJAdvisors 建造者
    this.aspectJAdvisorsBuilder =
        // 使用了适配器模式
        new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}

以上,AnnotationAwareAspectJAutoProxyCreator初始化结束,整个创建就完成了,主要是创建了aspectJAdvisorFactoryaspectJAdvisorsBuilder,它们负责保存和产生功能增强器

整个就是AnnotationAwareAspectJAutoProxyCreator中第一个被调用方法:initBeanFactory()的执行过程,都是在AnnotationAwareAspectJAutoProxyCreator实例化时执行的。

继续断点调试,来到了第二个执行的方法:isInfrastructureClass(Class<?> beanClass),源码如下

protected boolean isInfrastructureClass(Class<?> beanClass) {
    // isInfrastructureClass():返回给定的 bean 类是否表示不应被代理的基础结构类。默认实现将 Advices、Advisors 和 AopInfrastructureBeans 视为基础结构类。
    return (super.isInfrastructureClass(beanClass) ||
            // 判断给的类是否为一个切面,也就是标注了 @Aspect 注解
            (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}

注意,在这之前,AnnotationAwareAspectJAutoProxyCreator这个后置处理器以及创建完成了,那么在其他组件创建时,该后置处理器就会起作用,以上就是该后置处理器产生作用而执行的一段逻辑

执行的时机则是在十二大步的finishBeanFactoryInitialization()处,正是组件实例化的地方,具体的执行时机实在 createBean() 中的如下源码处

.....
try {
    // 让 BeanPostProcessors 有机会返回一个代理而不是目标 bean 实例
    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);
}
.....

之后则是调用后置处理逻辑,执行上面的isInfrastructureClass(Class<?> beanClass)方法,该方法主要就是判断其他组件是否需要被 aop 增强。

继续下一个断点,来到AnnotationAwareAspectJAutoProxyCreator中的findCandidateAdvisors()方法,

@Override
protected List<Advisor> findCandidateAdvisors() {
    // 找到所有增强器
    List<Advisor> advisors = super.findCandidateAdvisors();
    // 构建增强器
    if (this.aspectJAdvisorsBuilder != null) {
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}

findCandidateAdvisors()也是后置增强逻辑,倒推其执行逻辑,来到后置增强器调用处

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        // 判断组件是否需要被增强(上面第二个执行的 isInfrastructureClass() 方法也是由此被调用),是否需要跳过,也就是说需要增强的 bean 会被放在缓存中
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            // 将满足条件的组件放入 advisedBeans 中进行缓存
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

shouldSkip()源码如下

@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    // 找到目标 bean 的所有增强器,返回集合 candidateAdvisors
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    for (Advisor advisor : candidateAdvisors) {
        if (advisor instanceof AspectJPointcutAdvisor &&
            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
            return true;
        }
    }
    return super.shouldSkip(beanClass, beanName);
}

以上方法,最初调用的是postProcessBeforeInstantiation()后置增强逻辑,这其中调用到了isInfrastructureClass(beanClass)shouldSkip(beanClass, beanName),而在shouldSkip(beanClass, beanName)中又调用了findCandidateAdvisors()方法,findCandidateAdvisors()的特点在于,无论其他组件是否有增强器,都会执行构建增强器的逻辑,这一切都是在AnnotationAwareAspectJAutoProxyCreator等后置处理器创建后,后面的其他组件进入创建阶段时,第一个被创建的其他组件创建逻辑执行时开始执行的;

也就是说,每当其他组件创建一次,哪怕该组件没有标注@Aspect注解,也不需要增强,都会执行findCandidateAdvisors()中的:查找增强器构建增强器逻辑,这一切都是在其他组件实例化之前,通过AnnotationAwareAspectJAutoProxyCreator后置处理器的调用来实现,而后置处理逻辑的实现,在AnnotationAwareAspectJAutoProxyCreator的父类org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator中实现,只不过在父类的后置处理方法中,调用了子类重写的对应方法,如findCandidateAdvisors()shouldSkip()

既然无论怎样,findCandidateAdvisors()中的构建增强器逻辑:advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());都会执行,那就来看看其内部实现逻辑,借此,能够解析出 spring 是如何感知到切面组件的

public List<Advisor> buildAspectJAdvisors() {
    /*
   	得到所有切面的 beanName,在第一进入该方法时,也就是 bean 开始创建时,aspectBeanNames 的值为 null
    */
    List<String> aspectNames = this.aspectBeanNames;
    /*
    双检锁机制
    只在第一次运行且有切面存在时会进入 if 条件
    一旦第一次运行之后,找到了切面,下一次此 if 逻辑不会运行
    */
    if (aspectNames == null) {
        synchronized (this) {
            aspectNames = this.aspectBeanNames;
            if (aspectNames == null) {
                List<Advisor> advisors = new ArrayList<>();
                aspectNames = new ArrayList<>();
                // 获取所有的 beanName 且获取的是 Object 类型的
                String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this.beanFactory, Object.class, true, false);
                // 遍历分析所有组件
                for (String beanName : beanNames) {
                    if (!isEligibleBean(beanName)) {
                        continue;
                    }
                    // We must be careful not to instantiate beans eagerly as in this case they
                    // would be cached by the Spring container but would not have been weaved.
                    Class<?> beanType = this.beanFactory.getType(beanName);
                    if (beanType == null) {
                        continue;
                    }
                    // 判断组件是否是切面(是否标注 @Aspect 注解)
                    if (this.advisorFactory.isAspect(beanType)) {
                        // 将是切面的组件放入 aspectNames 集合
                        aspectNames.add(beanName);
                        AspectMetadata amd = new AspectMetadata(beanType, beanName);
                        if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                            MetadataAwareAspectInstanceFactory factory =
                                new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                           
                            List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                            if (this.beanFactory.isSingleton(beanName)) {
                                this.advisorsCache.put(beanName, classAdvisors);
                            }
                            else {
                                this.aspectFactoryCache.put(beanName, factory);
                            }
                            advisors.addAll(classAdvisors);
                        }
                        else {
                            // Per target or per this.
                            if (this.beanFactory.isSingleton(beanName)) {
                                throw new IllegalArgumentException("Bean with name '" + beanName +
                                                                   "' is a singleton, but aspect instantiation model is not singleton");
                            }
                            MetadataAwareAspectInstanceFactory factory =
                                new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                            this.aspectFactoryCache.put(beanName, factory);
                            advisors.addAll(this.advisorFactory.getAdvisors(factory));
                        }
                    }
                }
                // 最终将所有的切面组件名赋值给自身的 aspectBeanNames 属性
                this.aspectBeanNames = aspectNames;
                // 返回增强器
                return advisors;
            }
        }
    }

    /*
    同上,只在第一次运行且找到了切面后起作用
    */
    if (aspectNames.isEmpty()) {
        return Collections.emptyList();
    }
    List<Advisor> advisors = new ArrayList<>();
    for (String aspectName : aspectNames) {
        List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
        if (cachedAdvisors != null) {
            advisors.addAll(cachedAdvisors);
        }
        else {
            MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
            advisors.addAll(this.advisorFactory.getAdvisors(factory));
        }
    }
    // 最终返回所有切面中的所有advisors(增强器,也就是各种前置,后置通知)
    return advisors;
}

综合来看,spring aop 在其对应的后置处理逻辑第一次运行时,就完成了切面及其增强器(通知)的加载且放入了缓存,尽管后续的 bean 创建每次都会调用 aop 的后置处理器,但内部通过缓存加判断实现了幂等调用,不会重复获取和缓存 aop 切面信息

小总结

spring aop 的初始化和切面加载就是围绕AnnotationAwareAspectJAutoProxyCreator后置处理来实现的,首先在AnnotationAwareAspectJAutoProxyCreator初始化时,其aspectJAdvisorFactoryaspectJAdvisorsBuilder属性被初始化

之后,当其他 bean 创建时,AnnotationAwareAspectJAutoProxyCreator中后置处理相关逻辑被调用,但后置处理逻辑的调用处是其父类及其父类的父类,采取的是组合调用的形式,在后置处理被首次调用时,切面的相关信息就被加载到缓存中且后续每次后置处理逻辑被调用时,都不会重复加载切面数据,而且这个后置处理逻辑在其他 bean 创建之前和初始化时都会调用一次。

spring aop 在前面的这一堆操作最终构建了一些增强器,下面来研究这些增强器构建的细节,构建增强器的逻辑就在buildAspectJAdvisors()中,如下

public List<Advisor> buildAspectJAdvisors() {
    /*
   	得到所有切面的 beanName,在第一进入该方法时,也就是 bean 开始创建时,aspectBeanNames 的值为 null
    */
    List<String> aspectNames = this.aspectBeanNames;
    /*
    双检锁机制
    只在第一次运行且有切面存在时会进入 if 条件
    一旦第一次运行之后,找到了切面,下一次此 if 逻辑不会运行
    */
    if (aspectNames == null) {
        synchronized (this) {
            aspectNames = this.aspectBeanNames;
            if (aspectNames == null) {
                // 创建集合,用于存放增强器
                List<Advisor> advisors = new ArrayList<>();
                aspectNames = new ArrayList<>();
                // 获取所有的 beanName 且获取的是 Object 类型的
                String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this.beanFactory, Object.class, true, false);
                // 遍历分析所有组件
                for (String beanName : beanNames) {
                    if (!isEligibleBean(beanName)) {
                        continue;
                    }
                    // We must be careful not to instantiate beans eagerly as in this case they
                    // would be cached by the Spring container but would not have been weaved.
                    Class<?> beanType = this.beanFactory.getType(beanName);
                    if (beanType == null) {
                        continue;
                    }
                    // 判断组件是否是切面(是否标注 @Aspect 注解)
                    if (this.advisorFactory.isAspect(beanType)) {
                        // 将是切面的组件放入 aspectNames 集合
                        aspectNames.add(beanName);
                        AspectMetadata amd = new AspectMetadata(beanType, beanName);
                        if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                            MetadataAwareAspectInstanceFactory factory =
                                new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                            /*
                            this.advisorFactory.getAdvisors(factory);
                            使用 advisorFactory 获取增强器,存放到 classAdvisors 中
                            */
                            List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                            if (this.beanFactory.isSingleton(beanName)) {
                                this.advisorsCache.put(beanName, classAdvisors);
                            }
                            else {
                                this.aspectFactoryCache.put(beanName, factory);
                            }
                            advisors.addAll(classAdvisors);
                        }
                        else {
                            // Per target or per this.
                            if (this.beanFactory.isSingleton(beanName)) {
                                throw new IllegalArgumentException("Bean with name '" + beanName +
                                                                   "' is a singleton, but aspect instantiation model is not singleton");
                            }
                            MetadataAwareAspectInstanceFactory factory =
                                new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                            this.aspectFactoryCache.put(beanName, factory);
                            advisors.addAll(this.advisorFactory.getAdvisors(factory));
                        }
                    }
                }
                // 最终将所有的切面组名赋值给自身的 aspectBeanNames 属性
                this.aspectBeanNames = aspectNames;
                return advisors;
            }
        }
    }

    /*
    同上,只在第一次运行且找到了切面后起作用
    */
    if (aspectNames.isEmpty()) {
        return Collections.emptyList();
    }
    List<Advisor> advisors = new ArrayList<>();
    for (String aspectName : aspectNames) {
        List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
        if (cachedAdvisors != null) {
            advisors.addAll(cachedAdvisors);
        }
        else {
            MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
            advisors.addAll(this.advisorFactory.getAdvisors(factory));
        }
    }
    // 最终返回所有切面中的所有advisors(增强器,也就是各种前置,后置通知)
    return advisors;
}

断点打到List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);处,跟踪源码如下

@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
    // 得得当前外部遍历到的切面类
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
    validate(aspectClass);

    // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
    // so that it will only instantiate once.
    MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
        new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

    // 用于存放当前切面的中的增强器
    List<Advisor> advisors = new ArrayList<>();
    // getAdvisorMethods(aspectClass) 从切面类中获取所有方法
    for (Method method : getAdvisorMethods(aspectClass)) {
        // 将 getAdvisorMethods(aspectClass) 获取到的方法将进行遍历,调用 getAdvisor() 获取到其中的增强(通知)方法
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }

    // 需要懒加载的切面
    if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
        advisors.add(0, instantiationAdvisor);
    }

    // 需要增强的属性
    for (Field field : aspectClass.getDeclaredFields()) {
        Advisor advisor = getDeclareParentsAdvisor(field);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }

    return advisors;
}

追踪getAdvisor()方法,查看其中怎样判断是否为增强方法的

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
                          int declarationOrderInAspect, String aspectName) {

    // 校验切面类
    validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

    // 得到切入点
    AspectJExpressionPointcut expressionPointcut = getPointcut(
        candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    if (expressionPointcut == null) {
        return null;
    }

    // 利用切入点表达式,构建返回为增强器
    return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
                                                          this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

继续追踪getPointcut()

private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
		AspectJAnnotation<?> aspectJAnnotation =
            // 查找方法上的组件
				AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
		if (aspectJAnnotation == null) {
			return null;
		}

    	// 解析构建为切入点表达式
		AspectJExpressionPointcut ajexp =
				new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
		ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
		if (this.beanFactory != null) {
			ajexp.setBeanFactory(this.beanFactory);
		}
		return ajexp;
	}

关键方法在于findAspectJAnnotationOnMethod(candidateAdviceMethod);

protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
    // 遍历判断方法上的注解是否在指定的常量集合中有
    for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
        AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
        if (foundAnnotation != null) {
            return foundAnnotation;
        }
    }
    return null;
}

常量集合如下

private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};

这说明标注了以上几个注解的,都会被解析为一个与切面相关的方法

以上就是增强器的解析流程。

接下来探究切面类和增强类等 aop 相关组件的实例化的流程;首先是增强类的实例化,直接来到实例化流程中的 createBean() 处,在其实例化之前,会先执行如下代码

.....
try {
    // 让 BeanPostProcessors 有机会返回一个代理而不是目标 bean 实例
    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);
}
.....

追踪 resolveBeforeInstantiation() 方法

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                // 执行后置处理逻辑
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    // 如果返回了代理的实例对象,则直接为其执行初始化后的后置处理
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

来到applyBeanPostProcessorsBeforeInstantiation()逻辑中

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    // 遍历后置处理器,将后置处理器应用于目标组件
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

最终后置处理器的具体逻辑postProcessBeforeInstantiation()方法实现在org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator中,源码如下

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    // 得到组件对应的缓存
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        // 检查是否是已经分析过的组件
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        // 检查是否是切面,是否可以跳过
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    // Create proxy here if we have a custom TargetSource.
    // Suppresses unnecessary default instantiation of the target bean:
    // The TargetSource will handle target instances in a custom fashion.
    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
        if (StringUtils.hasLength(beanName)) {
            this.targetSourcedBeans.add(beanName);
        }
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    return null;
}

以上逻辑,尽管在当前 bean 为增强类HelloService的情况下,aop 依然没有为其返回一个代理的实例

既然 aop 没有珍惜创建代理对象的机会,那么接下来便是创建增强类HelloService实例的逻辑,实例的创建主要由 createBean() 中调用 doCreateBean() 实现,实例创建之后,又会执行如下后置处理

.....
// 允许后处理器修改合并的 bean 定义
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;
    }
}
.....

以上后置处理器中并没有 aop 相关类型的后置处理器,断点继续放行

接下来是属性赋值的环节,这里面也会调用后置处理器

// 任何 InstantiationAwareBeanPostProcessors 机会修改设置属性之前 bean 的状态
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }
}

此后置处理处 aop 介入了,但依然没有干什么事情

以上,在属性赋值环节,针对于增强类,aop 没有关键性的干预

赋值结束,下面进入初始化环节;在初始化环节中,aop 依然存在干预行为,源码如下

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

应用后置处理

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

在上述后置处理中,aop 的后置处理直接返回了原生的 bean 实例,断点放行

断点来到下一处后置处理逻辑

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

后置处理具体逻辑如下

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            // 对 bean 进行包装
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

wrapIfNecessary()源码如下

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 创建代理
    // getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); 获取指定 bean 中需要被代理的方法
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    // 如果当前 bean 中有需要被代理的方法
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

如果当前被后置处理的 bean 存在需要被增强的方法,则会被 aop 的后置处理器:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator为其创建代理对象

通过以上分析可以得出,aop 为切面类创建代理对象的时机,是在切面类实例化,属性赋值之后的初始化流程中,在applyBeanPostProcessorsAfterInitialization()方法中执行的。

根据上述源码,下面仔细研究 aop 创建代理对象的过程,首先一上来就调用getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);用于查找适合指定 bean 的增强器(从源码前面分析的流程中可知,这个增强器是已经创建好了的),其源码如下

protected Object[] getAdvicesAndAdvisorsForBean(
    Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    // 查找符合当前类的增强器
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

追踪findEligibleAdvisors(beanClass, beanName);源码

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 得到之前缓存的所有增强器
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 找到符合当前方法参数中的指定类的增强器
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

直接跟踪到底层方法,研究 aop 是怎么找到指定的增强器的

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    Assert.notNull(pc, "Pointcut must not be null");
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }

    // 通过切入点构造一个方法匹配器
    MethodMatcher methodMatcher = pc.getMethodMatcher();
    if (methodMatcher == MethodMatcher.TRUE) {
        // No need to iterate the methods if we're matching any method anyway...
        return true;
    }

    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    }

    Set<Class<?>> classes = new LinkedHashSet<>();
    if (!Proxy.isProxyClass(targetClass)) {
        classes.add(ClassUtils.getUserClass(targetClass));
    }
    classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

    for (Class<?> clazz : classes) {
        // 使用反射得到所有申明的方法集合
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        // 遍历方法集合
        for (Method method : methods) {
            if (introductionAwareMethodMatcher != null ?
                // 通过正则表达式解析的方式来判断对应的方法是否与切入点匹配
                introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                methodMatcher.matches(method, targetClass)) {
                return true;
            }
        }
    }

    return false;
}

以上流程:通过事先缓存好的增强器,使用切入点构造正则判断目标 bean 中的方法是否能够被增强,最终得到目标 bean 的所有增强器

回到findEligibleAdvisors(beanClass, beanName);中,在得到增强器后,会马上执行extendAdvisors(eligibleAdvisors);,使用得到的增强器创建一个增强器链,底层源码如下

public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
    // Don't add advisors to an empty list; may indicate that proxying is just not required
    if (!advisors.isEmpty()) {
        boolean foundAspectJAdvice = false;
        for (Advisor advisor : advisors) {
            // 判断增强器是否为 aspectj
            if (isAspectJAdvice(advisor)) {
                foundAspectJAdvice = true;
                break;
            }
        }
        
        /*
        向增强器集合中添加一个拦截器:
        官方文档对 ExposeInvocationInterceptor 的描述如下:
        将当前 MethodInvocation 公开为线程本地对象的拦截器。我们偶尔需要这样做;例如,当切入点(例如 AspectJ 表达式切入点)需要知道完整的调用上下文时。除非真的有必要,否则不要使用这个拦截器。目标对象通常不应该知道 Spring AOP,因为这会创建对 Spring API 的依赖。目标对象应该尽可能是普通的 POJO。如果使用,这个拦截器通常是拦截器链中的第一个。
        */
        if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
            advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
            return true;
        }
    }
    return false;
}

以上是对增强器的一个扩展操作,接下来依然回到findEligibleAdvisors(beanClass, beanName);中,紧接的就是对增强器集合中元素进行一个排序,按照前置通知 > 后置通知 > 返回通知等等顺序对增强器进行排序。

最后,回到最初创建代理的源码处,以上所有流程全在getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);被执行完毕,然后利用得到的增强器创建了一个代理对象。

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 创建代理
    // getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); 获取指定 bean 中需要被代理的方法
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    // 如果当前 bean 中有需要被代理的方法
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 创建一个目标 bean 的代理对象
        Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

创建代理对象时,底层会根据目标 bean 的实际情况来选择代理对象的创建方式,例如目标 bean 实现了接口,那么就会使用 jdk 的代理对象创建方式,否则使用 cglib 的创建方式

到此,已经把代理对象的创建进行了一个大概分析,aop 就是通过代理对象执行目标方法来完成对目标方法的功能增强的,接下来分析目标方法执行时的一些细节,直接在代理对象的方法调用处打上断点,凡是被 aop 增强的方法,在其调用时,都会先执行代理的回调,这里执行的是org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor中的intercept()方法,关键源码如下

// 获取拦截器和动态拦截建议
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);底层实现如下

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
    MethodCacheKey cacheKey = new MethodCacheKey(method);
    List<Object> cached = this.methodCache.get(cacheKey);
    if (cached == null) {
        // 将增强器转化为拦截器(在 debug 窗口中可以看到,增强器中只是保存了一些基本信息,而根据这些信息转化为拦截器后,才可以执行目标方法)
        cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
            this, method, targetClass);
        this.methodCache.put(cacheKey, cached);
    }
    return cached;
}

直接最终到底层,有如下关键源码

for (Advisor advisor : advisors) {
    if (advisor instanceof PointcutAdvisor) {
        // Add it conditionally.
        PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
        if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
            MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
            boolean match;
            if (mm instanceof IntroductionAwareMethodMatcher) {
                if (hasIntroductions == null) {
                    hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
                }
                match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
            }
            else {
                match = mm.matches(method, actualClass);
            }
            if (match) {
                MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                if (mm.isRuntime()) {
                    // Creating a new object instance in the getInterceptors() method
                    // isn't a problem as we normally cache created chains.
                    for (MethodInterceptor interceptor : interceptors) {
                        interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                    }
                }
                else {
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            }
        }
    }
    else if (advisor instanceof IntroductionAdvisor) {
        IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
        if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
            Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
        }
    }
    else {
        Interceptor[] interceptors = registry.getInterceptors(advisor);
        interceptorList.addAll(Arrays.asList(interceptors));
    }
}

遍历增强器,通过每次遍历得到的增强器去获取对应的方法拦截器数组,并且会根据增强器的类型(前置通知,后置通知,返回通知等)来选择构建不同类型的拦截器。

来到底层拦截器的获取逻辑

// 根据增强器的类型,这里返回了 AfterReturningAdviceInterceptor 拦截器实例
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
    AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
    return new AfterReturningAdviceInterceptor(advice);
}

AfterReturningAdviceInterceptor类如下

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

    private final AfterReturningAdvice advice;


    /**
	 * Create a new AfterReturningAdviceInterceptor for the given advice.
	 * @param advice the AfterReturningAdvice to wrap
	 */
    public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }


    // 目标方法的调用逻辑
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object retVal = mi.proceed();
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
}

通过以上方式获取完拦截器后,最终会在外层方法的调用处生成一个拦截器链:chain

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

拦截器链获取到后,开始创建 cglib 的方法调用器且执行了proceed();方法,触发了拦截器链的链式调用过程

retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

关于链式调用(责任链模式),可以参照相关的设计模式文章,推荐:http://c.biancheng.net/view/1383.html

下面解析在 spring aop 中目标增强方法拦截器的责任链模式执行流程,先直接上 proceed() 的源码

public Object proceed() throws Throwable {
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        // 如果没有拦截器的话,因为 currentInterceptorIndex 初始值为 -1,if 条件满足,直接执行目标方法。
        // 在 currentInterceptorIndex 为 -1 且等于 interceptorsAndDynamicMethodMatchers.size() 的情况下,有两种可能
        // 一种是上面提到过的,另外一种是有拦截器,currentInterceptorIndex 值随着拦截器的执行产生递增,当执行到了最终一个拦截器时,上述 if 条件依然满足。
        return invokeJoinpoint();
    }

    Object interceptorOrInterceptionAdvice =
        // 获取拦截器,每次获取后 currentInterceptorIndex++
        this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
       
        InterceptorAndDynamicMethodMatcher dm =
            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
        Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
        if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
            return dm.interceptor.invoke(this);
        }
        else {
           // 不匹配,跳过此拦截器(因为 0 索引处的拦截器是一个 ExposeInvocationInterceptor 用于线程之间共享数据的)
            return proceed();
        }
    }
    else {
        // 继续下一次链式调用
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

链式调用的关键在于invoke(this)中传入的 this,因为链式调用最初由当前类触发,它将自己传入invoke()中,那么在其他拦截器的invoke()方法中仍然可以通过这个this回到当前类中继续执行下一个链式调用,依次类推;

除去Before前置通知的拦截器会直接执行增强逻辑外,其他的拦截器会先执行proceed();方法,保证先将拦截器的执行链构造起来,当Before通知的拦截器执行完成后,执行链的索引已经到达拦截器数组的length - 1了,再次调用proceed();方法会直接执行目标方法,也就是上面源码中提到的第二种 if 条件满足的情况;注意,此时proceed();方法中已经执行了目标方法,根据源码来看,proceed();会直接返回,而在这之前,其他拦截器因为调用的都是同一个this所指向的proceed();方法,因此会按照调用的先后,依次等待proceed();执行完成返回结果,那么现在根据等待的先后顺序,目标方法之后,第一个接收到目标方法返回值的为 After 后置通知的拦截器,然后是返回通知的拦截器,如果目标方法有异常的话,该拦截器不会执行,而是执行异常通知的拦截器。

至此,整个 aop 源码的简单分析完成。

流程图总结如下

评论 3 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页

打赏作者

告别时光

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值