Spring Boot源码简析 AutowiredAnnotationBeanPostProcessor

相关阅读

简介

本文基于SpringBoot 2.6.2AutowiredAnnotationBeanPostProcessor的使用进行源码分析。

作用域

构造方法

每个Bean最多只能拥有一个标注了required属性设置为true的注解Autowired的构造方法,Spring容器会使用该构造方法创建Bean,并注入其依赖;但可以拥有多个标注了required属性未设置为true的注解Autowired的构造方法,这些构造方法都是候选构造方法,Spring容器会选择匹配Bean依赖最多的构造方法创建Bean,如果没有选出合适的构造方法,则使用首要/默认的构造方法如果存在的话;

@RestController
public class DemoController {

    private final DemoService demoService;


    @Autowired
    public DemoController(DemoService demoService) {
        this.demoService = demoService;
    }
}

字段

标注了注解Autowired的字段的依赖注入发生在构造方法调用之后,配置方法调用之前;

@RestController
public class DemoController {

    @Autowired
    private DemoService demoService;
}

配置方法

标注了注解Autowired的配置方法可以拥有随意的方法名和参数列表,每个参数都会在Spring容器中找到匹配的Bean;标注了注解Autowired的字段的setter方法是配置方法的一种特殊形式;

@RestController
public class DemoController {

    private DemoService demoService;

    @Autowired
    private void test(DemoService demoService) {
        this.demoService = demoService;
    }
}

@Lookup方法

标注了注解Lookup的方法会在运行时被Spring容器替换,即可以每次都是从Spring容器中获取最新的依赖(依赖为多例时,此时每次获取的依赖都不一样);

@RestController
public abstract class DemoController implements CommandLineRunner {

    @Lookup
    public abstract DemoService test();

    @Override
    public void run(String... args) throws Exception {
        for (int i = 0; i < 5; i++) {
            System.out.println(test());
        }
    }
}

简析

首先分析注入点的解析过程,然后再分析注入点的注入时机;

注入点解析

构造方法

AbstractAutowireCapableBeanFactory.createBeanInstance方法中会调用determineConstructorsFromBeanPostProcessors方法查找可以自动注入的候选构造方法,若存在,则调用autowireConstructor完成Bean创建,核心代码如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    ...

    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    ...
}

determineConstructorsFromBeanPostProcessors方法遍历执行Spring容器中所有的SmartInstantiationAwareBeanPostProcessordetermineCandidateConstructors方法,若得到的候选构造方法不为null则直接返回使用,代码如下:

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

    if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
        // 遍历容器中所有的SmartInstantiationAwareBeanPostProcessor
        for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
            Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
            if (ctors != null) {
                // 若存在则直接返回使用
                return ctors;
            }
        }
    }
    return null;
}

此时容器中会存在AutowiredAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessorAnnotationConfigUtil.registerAnnotationConfigProcessors中注册),构造方法和@Lookup方法的解析都在方法AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors中,其中构造方法解析的核心代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
        throws BeanCreationException {

    // @Lookup方法解析
    ...

    // 构造方法解析

    // 此处实现了缓存,若已处理则可以跳过
    Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
    if (candidateConstructors == null) {
        synchronized (this.candidateConstructorsCache) {
            candidateConstructors = this.candidateConstructorsCache.get(beanClass);
            // DCL
            if (candidateConstructors == null) {
                // 解析候选构造方法

                Constructor<?>[] rawCandidates;
                try {
                    rawCandidates = beanClass.getDeclaredConstructors();
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName,
                            "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                            "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
                }
                List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
                Constructor<?> requiredConstructor = null;
                Constructor<?> defaultConstructor = null;
                // 查找首要构造方法,非Kotlin类直接返回null
                Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                int nonSyntheticConstructors = 0;
                // 遍历本类的所有构造方法,无论访问权限
                for (Constructor<?> candidate : rawCandidates) {
                    if (!candidate.isSynthetic()) {
                        nonSyntheticConstructors++;
                    }
                    else if (primaryConstructor != null) {
                        continue;
                    }
                    // 查找构造方法上是否有注入注解(默认支持Autowired、Value、Inject)
                    MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
                    if (ann == null) {
                        Class<?> userClass = ClassUtils.getUserClass(beanClass);
                        if (userClass != beanClass) {
                            try {
                                Constructor<?> superCtor =
                                        userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                // 再次查找构造方法上是否有注入注解(默认支持Autowired、Value、Inject)
                                ann = findAutowiredAnnotation(superCtor);
                            }
                            catch (NoSuchMethodException ex) {
                                // Simply proceed, no equivalent superclass constructor found...
                            }
                        }
                    }
                    if (ann != null) {
                        if (requiredConstructor != null) {
                            // 已经存在标注了required属性设置为true的注解Autowired的构造方法,则不允许再有其它标注了注解Autowired的构造方法
                            throw new BeanCreationException(beanName,
                                    "Invalid autowire-marked constructor: " + candidate +
                                    ". Found constructor with 'required' Autowired annotation already: " +
                                    requiredConstructor);
                        }
                        // 注解的required属性是否为true
                        boolean required = determineRequiredStatus(ann);
                        if (required) {
                            if (!candidates.isEmpty()) {
                                throw new BeanCreationException(beanName,
                                        "Invalid autowire-marked constructors: " + candidates +
                                        ". Found constructor with 'required' Autowired annotation: " +
                                        candidate);
                            }
                            // 缓存标注了required属性设置为true的注解`Autowired`的构造方法
                            requiredConstructor = candidate;
                        }
                        // 缓存候选构造方法
                        candidates.add(candidate);
                    }
                    else if (candidate.getParameterCount() == 0) {
                        // 缓存默认构造方法
                        defaultConstructor = candidate;
                    }
                }
                if (!candidates.isEmpty()) {
                    if (requiredConstructor == null) {
                        if (defaultConstructor != null) {
                            // 添加默认构造方法,做为退路
                            candidates.add(defaultConstructor);
                        }
                        else if (candidates.size() == 1 && logger.isInfoEnabled()) {
                            // 此时仅有一个标注了required属性未设置为true的注解Autowired的构造方法,那么该注解的required属性等效为true
                            logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
                                    "': single autowire-marked constructor flagged as optional - " +
                                    "this constructor is effectively required since there is no " +
                                    "default constructor to fall back to: " + candidates.get(0));
                        }
                    }
                    candidateConstructors = candidates.toArray(new Constructor<?>[0]);
                }
                else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
                    // 仅存在一个有参数的构造方法,则作为候选构造方法
                    candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
                }
                else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
                        defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
                    // 使用首要和默认构造方法
                    candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
                }
                else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
                    // 仅使用首要构造方法
                    candidateConstructors = new Constructor<?>[] {primaryConstructor};
                }
                else {
                    // 无候选构造方法
                    candidateConstructors = new Constructor<?>[0];
                }
                this.candidateConstructorsCache.put(beanClass, candidateConstructors);
            }
        }
    }
    return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

字段

AbstractAutowireCapableBeanFactory.doCreateBean方法中创建出Bean实例后,会遍历执行Spring容器中所有MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition方法用于修改Bean的RootBeanDefinition,代码如下:

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
        processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    }
}

此时容器中会存在AutowiredAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessorAnnotationConfigUtil.registerAnnotationConfigProcessors中注册),其postProcessMergedBeanDefinition方法代码如下:

public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}

private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
    String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
    // 此处实现了缓存,若已处理则可以跳过
    InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
        synchronized (this.injectionMetadataCache) {
            metadata = this.injectionMetadataCache.get(cacheKey);
            if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                if (metadata != null) {
                    metadata.clear(pvs);
                }
                // 构建InjectionMetadata
                metadata = buildAutowiringMetadata(clazz);
                // 缓存
                this.injectionMetadataCache.put(cacheKey, metadata);
            }
        }
    }
    return metadata;
}

字段和配置方法的解析都在方法buildAutowiringMetadata中,其中字段解析的核心代码如下:

private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
    if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
        // 如果该类不支持注入注解,则直接返回
        return InjectionMetadata.EMPTY;
    }

    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

        // 字段的解析

        // 遍历本类的所有字段,无论访问权限
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            // 查找字段上是否有注入注解(默认支持Autowired、Value、Inject)
            MergedAnnotation<?> ann = findAutowiredAnnotation(field);
            if (ann != null) {
                if (Modifier.isStatic(field.getModifiers())) {
                    // 静态字段不支持注入注解
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation is not supported on static fields: " + field);
                    }
                    return;
                }
                // 注解的required属性是否为true
                boolean required = determineRequiredStatus(ann);
                // 缓存该待注入字段信息
                currElements.add(new AutowiredFieldElement(field, required));
            }
        });

        // 配置方法的解析
        ...

        elements.addAll(0, currElements);
        // 继续搜索父类,直到父类不存在或者父类就是Object类
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return InjectionMetadata.forElements(elements, clazz);
}

private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
    MergedAnnotations annotations = MergedAnnotations.from(ao);
    // 遍历支持的注入注解(默认支持Autowired、Value、Inject)
    for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
        MergedAnnotation<?> annotation = annotations.get(type);
        if (annotation.isPresent()) {
            // 存在则立即使用
            return annotation;
        }
    }
    return null;
}

protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
    return determineRequiredStatus(ann.<AnnotationAttributes> asMap(
        mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}

protected boolean determineRequiredStatus(AnnotationAttributes ann) {
    // 如果required属性不存在,或者其属性为true,则返回true;否则返回false
    // Autowired存在required属性,默认为true
    // Value不存在required属性
    // Inject不存在required属性
    return (!ann.containsKey(this.requiredParameterName) ||
            this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
}

配置方法

字段,配置方法的解析在方法AutowiredAnnotationBeanPostProcessor.buildAutowiringMetadata中,核心代码如下:

private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
    if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
        // 如果该类不支持注入注解,则直接返回
        return InjectionMetadata.EMPTY;
    }

    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

        // 字段的解析
        ...

        // 配置方法的解析

        // 遍历本类的所有方法,无论访问权限
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            // 获取原始方法(桥接方法是编译器生成的,而不是类定义的)
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            // 查找方法上是否有注入注解(默认支持Autowired、Value、Inject)
            MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                if (Modifier.isStatic(method.getModifiers())) {
                    // 静态方法不支持注入注解
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation is not supported on static methods: " + method);
                    }
                    return;
                }
                if (method.getParameterCount() == 0) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation should only be used on methods with parameters: " +
                                method);
                    }
                }
                // 注解的required属性是否为true
                boolean required = determineRequiredStatus(ann);
                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                // 缓存该配置方法信息
                currElements.add(new AutowiredMethodElement(method, required, pd));
            }
        });

        elements.addAll(0, currElements);
        // 继续搜索父类,直到父类不存在或者父类就是Object类
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return InjectionMetadata.forElements(elements, clazz);
}

@Lookup方法

构造方法@Lookup方法的解析是在AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors方法中,核心代码如下:

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
        throws BeanCreationException {

    // @Lookup方法解析

    // 此处实现了缓存,若已处理则可以跳过
    if (!this.lookupMethodsChecked.contains(beanName)) {
        // 如果该类不支持注入注解,则可以跳过
        if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
            try {
                Class<?> targetClass = beanClass;
                do {
                    // 遍历本类的所有方法,无论访问权限
                    ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                        // 查找方法上是否有Lookup注解
                        Lookup lookup = method.getAnnotation(Lookup.class);
                        if (lookup != null) {
                            Assert.state(this.beanFactory != null, "No BeanFactory available");
                            LookupOverride override = new LookupOverride(method, lookup.value());
                            try {
                                RootBeanDefinition mbd = (RootBeanDefinition)
                                        this.beanFactory.getMergedBeanDefinition(beanName);
                                // 添加该LookupOverride
                                mbd.getMethodOverrides().addOverride(override);
                            }
                            catch (NoSuchBeanDefinitionException ex) {
                                throw new BeanCreationException(beanName,
                                        "Cannot apply @Lookup to beans without corresponding bean definition");
                            }
                        }
                    });
                    // 继续搜索父类,直到父类不存在或者父类就是Object类
                    targetClass = targetClass.getSuperclass();
                }
                while (targetClass != null && targetClass != Object.class);

            }
            catch (IllegalStateException ex) {
                throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
            }
        }
        // 缓存该beanName,避免下次再处理
        this.lookupMethodsChecked.add(beanName);
    }

    // 构造方法解析
    ...
}

注入时机

构造方法

AbstractAutowireCapableBeanFactory.createBeanInstance方法中会调用determineConstructorsFromBeanPostProcessors方法查找可以自动注入的候选构造方法,若存在,则调用autowireConstructor完成Bean创建,核心代码如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    ...

    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    ...
}

protected BeanWrapper autowireConstructor(
        String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

    return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

ConstructorResolver.autowireConstructor方法中会找到合适的构造方法并得到参数列表,然后执行instantiate方法创建实例;

字段

字段的依赖注入发生在AbstractAutowireCapableBeanFactory.populateBean方法中,该方法会遍历执行Spring容器中所有的InstantiationAwareBeanPostProcessor.postProcessProperties方法,代码如下:

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

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

    ...
}

此时容器中会存在AutowiredAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessorAnnotationConfigUtil.registerAnnotationConfigProcessors中注册),其postProcessProperties方法代码如下:

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // 获取InjectionMetadata
    // 已经在postProcessMergedBeanDefinition方法中构建过,此时可以直接从缓存中获取
    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;
}

InjectionMetadata.inject方法代码如下:

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Collection<InjectedElement> checkedElements = this.checkedElements;
    Collection<InjectedElement> elementsToIterate =
            (checkedElements != null ? checkedElements : this.injectedElements);
    if (!elementsToIterate.isEmpty()) {
        // 遍历所有的InjectedElement
        // 1. AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement
        // 2. AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement
        for (InjectedElement element : elementsToIterate) {
            element.inject(target, beanName, pvs);
        }
    }
}

字段的依赖注入由AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement实现,代码如下:

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Field field = (Field) this.member;
    Object value;
    // 此处实现了缓存,若已处理则可以跳过
    if (this.cached) {
        try {
            // 获取缓存的字段值
            value = resolvedCachedArgument(beanName, this.cachedFieldValue);
        }
        catch (NoSuchBeanDefinitionException ex) {
            // 获取失败,则根据字段从Spring容器中获取字段值,并缓存,方便下次直接从缓存中获取
            value = resolveFieldValue(field, bean, beanName);
        }
    }
    else {
        // 根据字段从Spring容器中获取字段值,并缓存,方便下次直接从缓存中获取
        value = resolveFieldValue(field, bean, beanName);
    }
    if (value != null) {
        // 存在字段值,则注入
        ReflectionUtils.makeAccessible(field);
        field.set(bean, value);
    }
}

配置方法

字段配置方法的依赖注入由AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement实现,代码如下:

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    if (checkPropertySkipping(pvs)) {
        return;
    }
    Method method = (Method) this.member;
    Object[] arguments;
    if (this.cached) {
        try {
            // 获取缓存的方法参数列表
            arguments = resolveCachedArguments(beanName);
        }
        catch (NoSuchBeanDefinitionException ex) {
            // 根据方法从Spring容器中获取方法参数列表,并缓存,方便下次直接从缓存中获取
            arguments = resolveMethodArguments(method, bean, beanName);
        }
    }
    else {
        // 根据方法从Spring容器中获取方法参数列表,并缓存,方便下次直接从缓存中获取
        arguments = resolveMethodArguments(method, bean, beanName);
    }
    if (arguments != null) {
        try {
            // 存在方法参数,则执行方法完成依赖注入
            ReflectionUtils.makeAccessible(method);
            method.invoke(bean, arguments);
        }
        catch (InvocationTargetException ex) {
            throw ex.getTargetException();
        }
    }
}

@Lookup方法

构造方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值