跳至主要內容

13.@Autowired 等注解的实现原理

Java突击队大约 35 分钟

13.@Autowired 等注解的实现原理

该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址open in new window 进行阅读

Spring 版本:5.1.14.RELEASE

开始阅读这一系列文章之前,建议先查看《深入了解 Spring IoC(面试题)》open in new window这一篇文章

该系列其他文章请查看:《死磕 Spring 之 IoC 篇 - 文章导读》open in new window

@Autowired 等注解的实现原理

在上一篇《Bean 的属性填充阶段》open in new window文章中讲到,在创建一个 Bean 的实例对象后,会对这个 Bean 进行属性填充。在属性填充的过程中,获取到已定义的属性值,然后会通过 InstantiationAwareBeanPostProcessor 对该属性值进行处理,最后通过反射机制将属性值设置到这个 Bean 中。在 Spring 内部有以下两个 InstantiationAwareBeanPostProcessor 处理器:

  • AutowiredAnnotationBeanPostProcessor,解析 @Autowired 和 @Value 注解标注的属性,获取对应属性值
  • CommonAnnotationBeanPostProcessor,会解析 @Resource 注解标注的属性,获取对应的属性值

本文将会分析这两个处理器的实现,以及涉及到的相关对象

这两个处理器在哪被注册?

在前面的《解析自定义标签(XML 文件)》open in new window《BeanDefinition 的解析过程(面向注解)》open in new window文章中可以知道,在 XML 文件中的 <context:component-scan /> 标签的处理过程中,会底层借助于 ClassPathBeanDefinitionScanner 扫描器,去扫描指定路径下符合条件(@Component 注解)的 BeanDefinition 们,关于 @ComponentScan 注解的解析也是借助于这个扫描器实现的。扫描过程如下:

// ClassPathBeanDefinitionScanner.java
public int scan(String... basePackages) {
    // <1> 获取扫描前的 BeanDefinition 数量
    int beanCountAtScanStart = this.registry.getBeanDefinitionCount();

    // <2> 进行扫描,将过滤出来的所有的 .class 文件生成对应的 BeanDefinition 并注册
    doScan(basePackages);

    // Register annotation config processors, if necessary.
    // `<3>` 如果 includeAnnotationConfig 为 true(默认),则注册几个关于注解的 PostProcessor 处理器(关键)
    // 在其他地方也会注册,内部会进行判断,已注册的处理器不会再注册
    if (this.includeAnnotationConfig) {
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

    // <4> 返回本次扫描注册的 BeanDefinition 数量
    return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}

在第<3> 步会调用 AnnotationConfigUtils 的 registerAnnotationConfigProcessors(BeanDefinitionRegistry) 方法,如下:

// AnnotationConfigUtils.java
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
    registerAnnotationConfigProcessors(registry, null);
}

/**
 * Register all relevant annotation post processors in the given registry.
 * @param registry the registry to operate on
 * @param source the configuration source element (already extracted)
 * that this registration was triggered from. May be {@code null}.
 * @return a Set of BeanDefinitionHolders, containing all bean definitions
 * that have actually been registered by this call
 */
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);

    // 处理 Spring 应用上下文中的配置类
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 处理 @Autowired 以及 @Value 注解
    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));
    }

    // (条件激活)处理 JSR-250 注解 @Resource,如 @PostConstruct、@PreDestroy 等
    // 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));
    }

    // Processor 对象(条件激活)处理 JPA 注解场景
    // 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));
    }

    // 处理标注 @EventListener 的 Spring 事件监听方法
    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }

    // 用于 @EventListener 标注的事件监听方法构建成 ApplicationListener 对象
    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;
}

在这个方法中可以看到会注册 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor 两个处理器,然后在 Spring 应用上下文刷新阶段会将其初始化并添加至 AbstractBeanFactory 的 beanPostProcessors 集合中,那么接下来我们先来分析这两个处理器

回顾 Bean 的创建过程

第一步:回到《Bean 的创建过程》open in new window文章中的“对 RootBeanDefinition 加工处理”小节,会调用这个方法:

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

调用所有 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition 方法对 RootBeanDefinition 进行加工处理,例如:

  • AutowiredAnnotationBeanPostProcessor,会先解析出 @Autowired 和 @Value 注解标注的属性的注入元信息,后续进行依赖注入
  • CommonAnnotationBeanPostProcessor,会先解析出 @Resource 注解标注的属性的注入元信息,后续进行依赖注入,它也会找到 @PostConstruct 和 @PreDestroy 注解标注的方法,并构建一个 LifecycleMetadata 对象,用于后续生命周期中的初始化和销毁

第二步:回到《Bean 的创建过程》open in new window文章中的“属性填充”小节,该过程会进行下面的处理:

// `<5>` 通过 InstantiationAwareBeanPostProcessor 处理器(如果有)对 pvs 进行处理
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }

        // <5.1> 遍历所有的 BeanPostProcessor
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            // 如果为 InstantiationAwareBeanPostProcessor 类型
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // `<5.2>` 调用处理器的 postProcessProperties(...) 方法,对 pvs 进行后置处理
                PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                // <5.3> 如果上一步的处理结果为空,可能是新版本导致的(Spring 5.1 之前没有上面这个方法),则需要兼容老版本
                if (pvsToUse == null) {
                    // `<5.3.1>` 找到这个 Bean 的所有 java.beans.PropertyDescriptor 属性描述器(包含这个属性的所有信息)
                    if (filteredPds == null) {
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    // `<5.3.2>` 调用处理器的 postProcessPropertyValues(...) 方法,对 pvs 进行后置处理
                    pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    // `<5.3.3>` 如果处理后的 PropertyValues 对象为空,直接 return,则不会调用后面的 InstantiationAwareBeanPostProcessor 处理器,也不会进行接下来的属性填充
                    if (pvsToUse == null) {
                        return;
                    }
                }
                // `<5.4>` 将处理后的 pvsToUse 复制给 pvs
                pvs = pvsToUse;
            }
        }
    }

这里不会调用所有 InstantiationAwareBeanPostProcessor 的 postProcessProperties 方法对 pvs(MutablePropertyValues)属性值对象进行处理,例如:

  • AutowiredAnnotationBeanPostProcessor,会根据前面解析出来的 @Autowired 和 @Value 注解标注的属性的注入元信息,进行依赖注入
  • CommonAnnotationBeanPostProcessor,会根据前面解析出来的 @Resource 注解标注的属性的注入元信息,进行依赖注入

可以看到@Autowired@Value@Resource 注解的实现就是基于这两个处理器实现的,接下来我们来看看这两个处理器的具体实现

AutowiredAnnotationBeanPostProcessor

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor,主要处理 @Autowired@Value 注解进行依赖注入

体系结构

 

可以看到 AutowiredAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor 和 InstantiationAwareBeanPostProcessor 两个接口

构造方法

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
      implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

   /**
    * 保存需要处理的注解
    */
   private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);

   private String requiredParameterName = "required";

   private boolean requiredParameterValue = true;

   private int order = Ordered.LOWEST_PRECEDENCE - 2;

   @Nullable
   private ConfigurableListableBeanFactory beanFactory;

   private final Set<String> lookupMethodsChecked = Collections.newSetFromMap(new ConcurrentHashMap<>(256));

   private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = new ConcurrentHashMap<>(256);

   /**
	* 缓存需要注入的字段元信息
	*/
   private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);

   /**
    * Create a new {@code AutowiredAnnotationBeanPostProcessor} for Spring's
    * standard {@link Autowired @Autowired} annotation.
    * <p>Also supports JSR-330's {@link javax.inject.Inject @Inject} annotation,
    * if available.
    */
   @SuppressWarnings("unchecked")
   public AutowiredAnnotationBeanPostProcessor() {
      this.autowiredAnnotationTypes.add(Autowired.class);
      this.autowiredAnnotationTypes.add(Value.class);
      try {
         this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
               ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
         logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
      }
      catch (ClassNotFoundException ex) {
         // JSR-330 API not available - simply skip.
      }
   }
}

可以看到会添加 @Autowired@Value 两个注解,如果存在 JSR-330 的 javax.inject.Inject 注解,也是支持的

postProcessMergedBeanDefinition 方法

postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) 方法,找到 @Autowired@Value 注解标注的字段(或方法)的元信息,如下:

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    // 找到这个 Bean 所有需要注入的属性(@Autowired 或者 @Value 注解)
    InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}

直接调用 findAutowiringMetadata(...) 方法获取这个 Bean 的注入元信息对象

1. findAutowiringMetadata 方法
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
    // Fall back to class name as cache key, for backwards compatibility with custom callers.
    // 生成一个缓存 Key
    String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
    // Quick check on the concurrent map first, with minimal locking.
    // 先尝试从缓存中获取
    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);
                }
                // 构建一个需要注入的元信息对象
                metadata = buildAutowiringMetadata(clazz);
                this.injectionMetadataCache.put(cacheKey, metadata);
            }
        }
    }
    return metadata;
}

首先尝试从缓存中获取这个 Bean 对应的注入元信息对象,没有找到的话则调用 buildAutowiringMetadata(final Class<?> clazz) 构建一个,然后再放入缓存中

2. buildAutowiringMetadata 方法
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        // `<1>` 创建 currElements 集合,用于保存 @Autowired、@Value 注解标注的字段
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

        // <2> 遍历这个 Class 对象的所有字段
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            // `<2.1>` 找到该字段的 @Autowired 或者 @Value 注解,返回 ann 对象,没有的话返回空对象,则直接跳过不进行下面的操作
            AnnotationAttributes ann = findAutowiredAnnotation(field);
            if (ann != null) {
                // <2.2> 进行过滤,static 修饰的字段不进行注入
                if (Modifier.isStatic(field.getModifiers())) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Autowired annotation is not supported on static fields: " + field);
                    }
                    return;
                }
                // `<2.3>` 获取注解中的 required 配置
                boolean required = determineRequiredStatus(ann);
                // `<2.4>` 根据该字段和 required 构建一个 AutowiredFieldElement 对象,添加至 currElements
                currElements.add(new AutowiredFieldElement(field, required));
            }
        });

        // <3> 遍历这个 Class 对象的所有方法
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            // <3.1> 尝试找到这个方法的桥接方法,没有的话就是本身这个方法
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            // <3.2> 如果是桥接方法则直接跳过
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            // `<3.3>` 找到该方法的 @Autowired 或者 @Value 注解,返回 ann 对象,没有的话返回空对象,则直接跳过不进行下面的操作
            AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
            if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                // <3.4> 进行过滤,static 修饰的方法不进行注入
                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);
                    }
                }
                // `<3.5>` 获取注解中的 required 配置
                boolean required = determineRequiredStatus(ann);
                PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                // `<3.6>` 构建一个 AutowiredMethodElement 对象,添加至 currElements
                currElements.add(new AutowiredMethodElement(method, required, pd));
            }
        });

        elements.addAll(0, currElements);
        // <4> 找到父类,循环遍历
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    // <5> 根据从这个 Bean 解析出来的所有 InjectedElement 对象生成一个 InjectionMetadata 注入元信息对象,并返回
    return new InjectionMetadata(clazz, elements);
}

过程如下:

1、 创建currElements集合,用于保存@Autowired@Value注解标注的字段;
2、 遍历这个Class对象的所有字段;

1、 找到该字段的@Autowired或者@Value注解,返回ann对象,没有的话返回空对象,则直接跳过不进行下面的操作;
2、 进行过滤,static修饰的字段不进行注入;
3、 获取注解中的required配置;
4、 根据该字段和required构建一个AutowiredFieldElement对象,添加至currElements
3、 遍历这个Class对象的所有方法;

1、 尝试找到这个方法的桥接方法,没有的话就是本身这个方法;
2、 如果是桥接方法则直接跳过;
3、 找到该方法的@Autowired或者@Value注解,返回ann对象,没有的话返回空对象,则直接跳过不进行下面的操作;
4、 进行过滤,static修饰的方法不进行注入;
5、 获取注解中的required配置;
6、 构建一个AutowiredMethodElement对象,添加至currElements
4、 找到父类,循环遍历;
5、 根据从这个Bean解析出来的所有InjectedElement对象生成一个InjectionMetadata注入元信息对象,并返回;

整个过程很简单,就是解析出所有 @Autowired 或者 @Value 注解标注的方法或者字段,然后构建一个 InjectionMetadata 注入元信息对象

postProcessProperties 方法

postProcessProperties(PropertyValues pvs, Object bean, String beanName) 方法,根据 @Autowired@Value 注解标注的字段(或方法)的元信息进行依赖注入,如下:

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // 找到这个 Bean 的注入元信息对象
    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 的注入元信息对象,上面已经讲过了,然后调用其 inject(...) 方法,这里先来看到 InjectionMetadata 这个对象

InjectionMetadata 注入元信息对象

org.springframework.beans.factory.annotation.InjectionMetadata,某个 Bean 的注入元信息对象

public class InjectionMetadata {

	private static final Log logger = LogFactory.getLog(InjectionMetadata.class);

	private final Class<?> targetClass;

	/**
	 * 需要注入的字段(或方法)的元信息
	 */
	private final Collection<InjectedElement> injectedElements;

	@Nullable
	private volatile Set<InjectedElement> checkedElements;

	public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
		this.targetClass = targetClass;
		this.injectedElements = elements;
	}

	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()) {
			for (InjectedElement element : elementsToIterate) {
				if (logger.isTraceEnabled()) {
					logger.trace("Processing injected element of bean '" + beanName + "': " + element);
				}
				element.inject(target, beanName, pvs);
			}
		}
	}
}

可以看到注入方法非常简单,就是遍历所有的 InjectedElement 对象,调用他们的 inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) 方法

AutowiredFieldElement

AutowiredAnnotationBeanPostProcessor 的私有内部类,注入字段对象,如下:

private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
    /** 是否必须 */
    private final boolean required;
    /** 是否缓存起来了 */
    private volatile boolean cached = false;
    /** 缓存的对象 */
    @Nullable
    private volatile Object cachedFieldValue;

    public AutowiredFieldElement(Field field, boolean required) {
        super(field, null);
        this.required = required;
    }

    @Override
    protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        // `<1>` 获取 field 字段
        Field field = (Field) this.member;
        Object value;
        // <2> 如果进行缓存了,则尝试从缓存中获取
        if (this.cached) {
            value = resolvedCachedArgument(beanName, this.cachedFieldValue);
        }
        // <3> 否则,开始进行解析
        else {
            // `<3.1>` 创建一个依赖注入描述器 desc
            DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
            desc.setContainingClass(bean.getClass());
            Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
            Assert.state(beanFactory != null, "No BeanFactory available");
            TypeConverter typeConverter = beanFactory.getTypeConverter();
            try {
                /**
                 * <3.2> 通过 {@link org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency} 方法
                 * 找到这个字段对应的 Bean(们)
                 */
                value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
            }
            catch (BeansException ex) {
                throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
            }
            // <3.3> 和缓存相关,如果有必要则将本次找到的注入对象缓存起来,避免下次再进行解析
            synchronized (this) {
                if (!this.cached) {
                    if (value != null || this.required) {
                        this.cachedFieldValue = desc;
                        registerDependentBeans(beanName, autowiredBeanNames);
                        if (autowiredBeanNames.size() == 1) {
                            String autowiredBeanName = autowiredBeanNames.iterator().next();
                            if (beanFactory.containsBean(autowiredBeanName) &&
                                    beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                                this.cachedFieldValue = new ShortcutDependencyDescriptor(
                                        desc, autowiredBeanName, field.getType());
                            }
                        }
                    }
                    else {
                        this.cachedFieldValue = null;
                    }
                    this.cached = true;
                }
            }
        }
        // <4> 如果获取到该字段对应的对象,则进行属性赋值(依赖注入)
        if (value != null) {
            ReflectionUtils.makeAccessible(field);
            field.set(bean, value);
        }
    }
}

直接看到 inject(...) 方法,注入的过程如下:

1、 获取field字段;
2、 如果进行缓存了,则尝试从缓存中获取;
3、 否则,开始进行解析;

1、 创建一个依赖注入描述器desc
2. **【核心】**通过 DefaultListableBeanFactory#resolveDependency(...) 方法,找到这个字段对应的 Bean(们)
3、 和缓存相关,如果有必要则将本次找到的注入对象缓存起来,避免下次再进行解析;
4、 如果获取到该字段对应的对象,则进行属性赋值(依赖注入),底层就是通过反射机制为该字段赋值;

可以看到整个的核心在于通过 DefaultListableBeanFactory#resolveDependency(...) 方法找到字段对应的 Bean,这里也许是一个集合对象,所以也可能找到的是多个 Bean,该方法在后面进行分析

AutowiredMethodElement

AutowiredAnnotationBeanPostProcessor 的私有内部类,注入方法对象,如下:

private class AutowiredMethodElement extends InjectionMetadata.InjectedElement {
    /** 是否必须 */
    private final boolean required;
    /** 是否缓存起来了 */
    private volatile boolean cached = false;
    /** 缓存的方法参数对象 */
    @Nullable
    private volatile Object[] cachedMethodArguments;

    public AutowiredMethodElement(Method method, boolean required, @Nullable PropertyDescriptor pd) {
        super(method, pd);
        this.required = required;
    }

    @Override
    protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        if (checkPropertySkipping(pvs)) {
            return;
        }
        // `<1>` 获取 method 方法
        Method method = (Method) this.member;
        // <2> 如果进行缓存了,则尝试从缓存中获取方法参数对象
        Object[] arguments;
        if (this.cached) {
            // Shortcut for avoiding synchronization...
            arguments = resolveCachedArguments(beanName);
        }
        // <3> 否则,开始进行解析
        else {
            // `<3.1>` 获取方法的参数类型集合 paramTypes,根据参数位置确定参数
            Class<?>[] paramTypes = method.getParameterTypes();
            arguments = new Object[paramTypes.length];
            // `<3.2>` 构建一个依赖注入描述器数组 descriptors,用于保存后续创建的对象
            DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
            Set<String> autowiredBeans = new LinkedHashSet<>(paramTypes.length);
            Assert.state(beanFactory != null, "No BeanFactory available");
            TypeConverter typeConverter = beanFactory.getTypeConverter();
            // <3.3> 根据参数顺序遍历该方法的参数
            for (int i = 0; i < arguments.length; i++) {
                // `<3.3.1>` 为第 i 个方法参数创建一个 MethodParameter 对象
                MethodParameter methodParam = new MethodParameter(method, i);
                // `<3.3.2>` 创建依赖描述器 currDesc,并添加至 descriptors 数组
                DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
                currDesc.setContainingClass(bean.getClass());
                descriptors[i] = currDesc;
                try {
                    /**
                     * <3.3.3> 通过 {@link org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency} 方法
                     * 找到这个方法参数对应的 Bean(们)
                     */
                    Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
                    if (arg == null && !this.required) {
                        arguments = null;
                        break;
                    }
                    arguments[i] = arg;
                }
                catch (BeansException ex) {
                    throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
                }
            }
            // <3.4> 和缓存相关,如果有必要则将本次找到的方法参数对象缓存起来,避免下次再进行解析
            synchronized (this) {
                if (!this.cached) {
                    if (arguments != null) {
                        Object[] cachedMethodArguments = new Object[paramTypes.length];
                        System.arraycopy(descriptors, 0, cachedMethodArguments, 0, arguments.length);
                        registerDependentBeans(beanName, autowiredBeans);
                        if (autowiredBeans.size() == paramTypes.length) {
                            Iterator<String> it = autowiredBeans.iterator();
                            for (int i = 0; i < paramTypes.length; i++) {
                                String autowiredBeanName = it.next();
                                if (beanFactory.containsBean(autowiredBeanName) &&
                                        beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
                                    cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
                                            descriptors[i], autowiredBeanName, paramTypes[i]);
                                }
                            }
                        }
                        this.cachedMethodArguments = cachedMethodArguments;
                    }
                    else {
                        this.cachedMethodArguments = null;
                    }
                    this.cached = true;
                }
            }
        }
        // <4> 如果找到该方法的参数(们),则进行属性赋值(依赖注入)
        if (arguments != null) {
            try {
                ReflectionUtils.makeAccessible(method);
                // 通过反射机制调用该方法
                method.invoke(bean, arguments);
            }
            catch (InvocationTargetException ex) {
                throw ex.getTargetException();
            }
        }
    }
}

直接看到 inject(...) 方法,注入的过程如下:

1、 获取method方法;
2、 如果进行缓存了,则尝试从缓存中获取方法参数对象;
3、 否则,开始进行解析;

1、 获取方法的参数类型集合paramTypes,根据参数位置确定参数;
2、 构建一个依赖注入描述器数组descriptors,用于保存后续创建的对象;
3、 根据参数顺序遍历该方法的参数;

1.  为第 `i` 个方法参数创建一个 MethodParameter 对象
2.  创建依赖描述器 `currDesc`,并添加至 `descriptors` 数组
    3.  **【核心】**通过 DefaultListableBeanFactory#resolveDependency(...) 方法,找到这个方法参数对应的 Bean(们)
4.  和缓存相关,如果有必要则将本次找到的方法参数对象缓存起来,避免下次再进行解析

4、 如果找到该方法的参数(们),则进行属性赋值(依赖注入),底层就是通过反射机制调用该方法;

可以看到整个的核心也是通过 DefaultListableBeanFactory#resolveDependency(...) 方法找到方法参数对应的 Bean,该方法在后面进行分析

CommonAnnotationBeanPostProcessor

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor,主要处理 @Resource 注解进行依赖注入,以及 @PostConstruct@PreDestroy 生命周期注解的处理

体系结构

 

可以看到 CommonAnnotationBeanPostProcessor 实现了 MergedBeanDefinitionPostProcessor 和 InstantiationAwareBeanPostProcessor 两个接口,还实现了 DestructionAwareBeanPostProcessor 接口,用于生命周期中的初始化和销毁的处理

构造方法

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
		implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {

	@Nullable
	private static Class<? extends Annotation> webServiceRefClass;

	@Nullable
	private static Class<? extends Annotation> ejbRefClass;

	static {
		try {
			@SuppressWarnings("unchecked")
			Class<? extends Annotation> clazz = (Class<? extends Annotation>)
					ClassUtils.forName("javax.xml.ws.WebServiceRef", CommonAnnotationBeanPostProcessor.class.getClassLoader());
			webServiceRefClass = clazz;
		}
		catch (ClassNotFoundException ex) {
			webServiceRefClass = null;
		}
		try {
			@SuppressWarnings("unchecked")
			Class<? extends Annotation> clazz = (Class<? extends Annotation>)
					ClassUtils.forName("javax.ejb.EJB", CommonAnnotationBeanPostProcessor.class.getClassLoader());
			ejbRefClass = clazz;
		}
		catch (ClassNotFoundException ex) {
			ejbRefClass = null;
		}
	}

	/**
	 * Create a new CommonAnnotationBeanPostProcessor,
	 * with the init and destroy annotation types set to
	 * {@link javax.annotation.PostConstruct} and {@link javax.annotation.PreDestroy},
	 * respectively.
	 */
	public CommonAnnotationBeanPostProcessor() {
		setOrder(Ordered.LOWEST_PRECEDENCE - 3);
		setInitAnnotationType(PostConstruct.class);
		setDestroyAnnotationType(PreDestroy.class);
		ignoreResourceType("javax.xml.ws.WebServiceContext");
	}
}

public class InitDestroyAnnotationBeanPostProcessor
		implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {

	protected transient Log logger = LogFactory.getLog(getClass());

	/**
	 * 初始化注解,默认为 @PostConstruct
	 */
	@Nullable
	private Class<? extends Annotation> initAnnotationType;

	/**
	 * 销毁注解,默认为 @PreDestroy
	 */
	@Nullable
	private Class<? extends Annotation> destroyAnnotationType;

	private int order = Ordered.LOWEST_PRECEDENCE;

	@Nullable
	private final transient Map<Class<?>, LifecycleMetadata> lifecycleMetadataCache = new ConcurrentHashMap<>(256);

	public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
		this.initAnnotationType = initAnnotationType;
	}

	public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType) {
		this.destroyAnnotationType = destroyAnnotationType;
	}
}

可以看到会设置初始化注解为 @PostConstruct,销毁注解为 @PreDestroy,这两个注解都是 JSR-250 注解;另外如果存在 javax.xml.ws.WebServiceRefjavax.ejb.EJB 注解也是会进行设置的

postProcessMergedBeanDefinition 方法

postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) 方法,找到 @PostConstruct@PreDestroy 注解标注的方法,并构建 LifecycleMetadata 对象,找到 @Resource 注解标注的字段(或方法)的元信息,如下:

// CommonAnnotationBeanPostProcessor.java
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    // 先调用父类的方法,找到 @PostConstruct 和 @PreDestroy 注解标注的方法,并构建 LifecycleMetadata 对象
    super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
    // 找到 @Resource 注解标注的字段(或方法),构建一个 InjectionMetadata 对象,用于后续的属性注入
    InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}

整个的过程原理和 AutowiredAnnotationBeanPostProcessor 差不多,先从缓存中获取,未命中则调用对应的方法进行构建,下面先来看看父类中的方法

buildLifecycleMetadata 方法
// InitDestroyAnnotationBeanPostProcessor.java
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
    List<LifecycleElement> initMethods = new ArrayList<>();
    List<LifecycleElement> destroyMethods = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<LifecycleElement> currInitMethods = new ArrayList<>();
        final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
                LifecycleElement element = new LifecycleElement(method);
                currInitMethods.add(element);
                if (logger.isTraceEnabled()) {
                    logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
                }
            }
            if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
                currDestroyMethods.add(new LifecycleElement(method));
                if (logger.isTraceEnabled()) {
                    logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
                }
            }
        });

        initMethods.addAll(0, currInitMethods);
        destroyMethods.addAll(currDestroyMethods);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return new LifecycleMetadata(clazz, initMethods, destroyMethods);
}

整个过程比较简单,找到这个 Bean 中 @PostConstruct@PreDestroy 注解标注的方法,然后构建一个 LifecycleMetadata 生命周期元信息对象

buildResourceMetadata 方法
// CommonAnnotationBeanPostProcessor.java
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
    Class<?> targetClass = clazz;

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

        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
                }
                currElements.add(new WebServiceRefElement(field, field, null));
            }
            else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@EJB annotation is not supported on static fields");
                }
                currElements.add(new EjbRefElement(field, field, null));
            }
            else if (field.isAnnotationPresent(Resource.class)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@Resource annotation is not supported on static fields");
                }
                if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
                    currElements.add(new ResourceElement(field, field, null));
                }
            }
        });

        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
                    }
                    if (method.getParameterCount() != 1) {
                        throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
                    }
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
                }
                else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("@EJB annotation is not supported on static methods");
                    }
                    if (method.getParameterCount() != 1) {
                        throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
                    }
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    currElements.add(new EjbRefElement(method, bridgedMethod, pd));
                }
                else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("@Resource annotation is not supported on static methods");
                    }
                    Class<?>[] paramTypes = method.getParameterTypes();
                    if (paramTypes.length != 1) {
                        throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
                    }
                    if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
                        PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                        currElements.add(new ResourceElement(method, bridgedMethod, pd));
                    }
                }
            }
        });

        elements.addAll(0, currElements);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return new InjectionMetadata(clazz, elements);
}

整个过程也比较简单,解析出这个 Bean 带有 @Resource 注解的所有字段(或方法),构建成对应的 ResourceElement 对象,然后再构建成一个 InjectionMetadata 注入元信息对象

postProcessProperties 方法

postProcessProperties(PropertyValues pvs, Object bean, String beanName) 方法,根据 @Resource 注解标注的字段(或方法)的元信息进行依赖注入,如下:

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
    try {
        // 进行注入
        metadata.inject(bean, beanName, pvs);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
    }
    return pvs;
}

先找到这个 Bean 的注入元信息对象,上面已经讲过了,然后调用其 inject(...) 方法,该对象上面已经讲过了,实际就是调用其内部 InjectedElement 的 inject(...) 方法

postProcessBeforeInitialization 方法

初始化Bean 的时候会先执行 @PostConstruct 标注的初始化方法

// InitDestroyAnnotationBeanPostProcessor.java
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 找到 @PostConstruct 和 @PreDestroy 注解标注的方法们所对应的 LifecycleMetadata 对象
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
        // 执行 @PostConstruct 标注的初始化方法
        metadata.invokeInitMethods(bean, beanName);
    }
    catch (InvocationTargetException ex) {
        throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
    }
    return bean;
}
// InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata
public void invokeInitMethods(Object target, String beanName) throws Throwable {
    Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
    Collection<LifecycleElement> initMethodsToIterate =
            (checkedInitMethods != null ? checkedInitMethods : this.initMethods);
    if (!initMethodsToIterate.isEmpty()) {
        for (LifecycleElement element : initMethodsToIterate) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
            }
            element.invoke(target);
        }
    }
}

postProcessBeforeDestruction 方法

销毁Bean 的时候先执行 @PreDestroy 注解标注的销毁方法

// InitDestroyAnnotationBeanPostProcessor.java
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
    // 找到 @PostConstruct 和 @PreDestroy 注解标注的方法们所对应的 LifecycleMetadata 对象
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
        // 执行 @PreDestroy 标注的销毁方法
        metadata.invokeDestroyMethods(bean, beanName);
    }
    catch (InvocationTargetException ex) {
        String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
        if (logger.isDebugEnabled()) {
            logger.warn(msg, ex.getTargetException());
        }
        else {
            logger.warn(msg + ": " + ex.getTargetException());
        }
    }
    catch (Throwable ex) {
        logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
    }
}
// InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata
public void invokeDestroyMethods(Object target, String beanName) throws Throwable {
    Collection<LifecycleElement> checkedDestroyMethods = this.checkedDestroyMethods;
    Collection<LifecycleElement> destroyMethodsToUse =
            (checkedDestroyMethods != null ? checkedDestroyMethods : this.destroyMethods);
    if (!destroyMethodsToUse.isEmpty()) {
        for (LifecycleElement element : destroyMethodsToUse) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
            }
            element.invoke(target);
        }
    }
}

ResourceElement

CommonAnnotationBeanPostProcessor 的私有内部类,@Resource 注入字段(或方法)对象

构造方法

protected abstract class LookupElement extends InjectionMetadata.InjectedElement {

    /** Bean 的名称 */
    protected String name = "";
	/** 是否为默认的名称(通过注解定义的) */
    protected boolean isDefaultName = false;
	/** Bean 的类型 */
    protected Class<?> lookupType = Object.class;

    @Nullable
    protected String mappedName;

    public LookupElement(Member member, @Nullable PropertyDescriptor pd) {
        super(member, pd);
    }
    
    public final DependencyDescriptor getDependencyDescriptor() {
        if (this.isField) {
            return new LookupDependencyDescriptor((Field) this.member, this.lookupType);
        }
        else {
            return new LookupDependencyDescriptor((Method) this.member, this.lookupType);
        }
    }
}

private class ResourceElement extends LookupElement {
	/** 是否延迟加载 */
    private final boolean lazyLookup;

    public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
        super(member, pd);
        Resource resource = ae.getAnnotation(Resource.class);
        String resourceName = resource.name();
        Class<?> resourceType = resource.type();
        this.isDefaultName = !StringUtils.hasLength(resourceName);
        if (this.isDefaultName) {
            resourceName = this.member.getName();
            if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
                resourceName = Introspector.decapitalize(resourceName.substring(3));
            }
        }
        else if (embeddedValueResolver != null) {
            resourceName = embeddedValueResolver.resolveStringValue(resourceName);
        }
        if (Object.class != resourceType) {
            checkResourceType(resourceType);
        }
        else {
            // No resource type specified... check field/method.
            resourceType = getResourceType();
        }
        this.name = (resourceName != null ? resourceName : "");
        this.lookupType = resourceType;
        String lookupValue = resource.lookup();
        this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
        Lazy lazy = ae.getAnnotation(Lazy.class);
        this.lazyLookup = (lazy != null && lazy.value());
    }
}

ResourceElement 的构造方法会通过 @Resource 注解和该字段(或方法)解析出基本信息

可以看到还继承了 InjectionMetadata 的静态内部类 InjectedElement,我们先来看到这个类的 inject(...) 方法

inject 方法

public abstract static class InjectedElement {

    protected final Member member;

    protected final boolean isField;

    protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
            throws Throwable {
        if (this.isField) {
            Field field = (Field) this.member;
            ReflectionUtils.makeAccessible(field);
            field.set(target, getResourceToInject(target, requestingBeanName));
        } else {
            if (checkPropertySkipping(pvs)) {
                return;
            }
            try {
                Method method = (Method) this.member;
                ReflectionUtils.makeAccessible(method);
                method.invoke(target, getResourceToInject(target, requestingBeanName));
            }
            catch (InvocationTargetException ex) {
                throw ex.getTargetException();
            }
        }
    }
    
    @Nullable
	protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
		return null;
	}
}

不管是字段还是方法,底层都是通过反射机制进行赋值或者调用,都会调用 getResourceToInject(...) 方法获取到字段值或者方法参数

getResourceToInject 方法

@Override
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
    return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
            getResource(this, requestingBeanName));
}

如果是延迟加载,则调用 buildLazyResourceProxy(...) 方法返回一个代理对象,如下:

protected Object buildLazyResourceProxy(final LookupElement element, final @Nullable String requestingBeanName) {
    TargetSource ts = new TargetSource() {
        @Override
        public Class<?> getTargetClass() {
            return element.lookupType;
        }
        @Override
        public boolean isStatic() {
            return false;
        }
        @Override
        public Object getTarget() {
            return getResource(element, requestingBeanName);
        }
        @Override
        public void releaseTarget(Object target) {
        }
    };
    ProxyFactory pf = new ProxyFactory();
    pf.setTargetSource(ts);
    if (element.lookupType.isInterface()) {
        pf.addInterface(element.lookupType);
    }
    ClassLoader classLoader = (this.beanFactory instanceof ConfigurableBeanFactory ?
            ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() : null);
    return pf.getProxy(classLoader);
}

否则,调用 getResource(...) 方法获取注入对象

getResource 方法

protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
        throws NoSuchBeanDefinitionException {

    if (StringUtils.hasLength(element.mappedName)) {
        return this.jndiFactory.getBean(element.mappedName, element.lookupType);
    }
    if (this.alwaysUseJndiLookup) {
        return this.jndiFactory.getBean(element.name, element.lookupType);
    }
    if (this.resourceFactory == null) {
        throw new NoSuchBeanDefinitionException(element.lookupType,
                "No resource factory configured - specify the 'resourceFactory' property");
    }
    return autowireResource(this.resourceFactory, element, requestingBeanName);
}

前面的判断忽略掉,直接看到最后会调用 autowireResource(...) 方法,并返回注入信息

autowireResource 方法

protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
        throws NoSuchBeanDefinitionException {

    Object resource;
    Set<String> autowiredBeanNames;
    String name = element.name;

    if (factory instanceof AutowireCapableBeanFactory) {
        AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory;
        DependencyDescriptor descriptor = element.getDependencyDescriptor();
        if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) {
            autowiredBeanNames = new LinkedHashSet<>();
            resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null);
            if (resource == null) {
                throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
            }
        }
        else {
            resource = beanFactory.resolveBeanByName(name, descriptor);
            autowiredBeanNames = Collections.singleton(name);
        }
    }
    else {
        resource = factory.getBean(name, element.lookupType);
        autowiredBeanNames = Collections.singleton(name);
    }

    if (factory instanceof ConfigurableBeanFactory) {
        ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
        for (String autowiredBeanName : autowiredBeanNames) {
            if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
                beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
            }
        }
    }

    return resource;
}

@Resource 注解相比于 @Autowired 注解的处理更加复杂点,可以如果 @Resource 指定了名称,则直接通过依赖查找获取该名称的 Bean,否则,和 @Autowired 一样去调用 DefaultListableBeanFactory#resolveDependency(...) 方法,找到对应的注入对象,该方法在后面进行分析

1. resolveDependency 处理依赖方法

resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) 方法,找到对应的依赖 Bean,该方法在《Bean 的创建过程》open in new window中也提到了,获取 Bean 的实例对象时,构造器注入的参数也是通过该方法获取的,本文的依赖注入底层也是通过该方法实现的,这里我们对该方法一探究竟

// DefaultListableBeanFactory.java
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
        @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

    // <1> 设置参数名称探测器,例如通过它获取方法参数的名称
    descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
    // <2> 如果依赖类型为 Optional 类型
    if (Optional.class == descriptor.getDependencyType()) {
        // 调用 createOptionalDependency(...) 方法,先将 descriptor 注入表述器封装成 NestedDependencyDescriptor 对象
        // 底层处理和下面的 5.2 相同
        return createOptionalDependency(descriptor, requestingBeanName);
    }
    // <3> 否则,如果依赖类型为 ObjectFactory 或 ObjectProvider 类型
    else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) {
        // 返回一个 DependencyObjectProvider 私有内部类对象,并没有获取到实例的 Bean,需要调用其 getObject() 方法获取目标对象
        return new DependencyObjectProvider(descriptor, requestingBeanName);
    }
    // <4> 否则,如果依赖类型为 javax.inject.Provider 类型
    else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
        // 返回一个 Jsr330Provider 私有内部类对象,该对象也继承 DependencyObjectProvider
        return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
    }
    // <5> 否则,通用的处理逻辑
    else {
        // <5.1> 先通过 AutowireCandidateResolver 尝试获取一个代理对象,延迟依赖注入则会返回一个代理对象
        Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
        // `<5.2>` 如果上面没有返回代理对象,则进行处理,调用 doResolveDependency(...) 方法
        if (result == null) {
            result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
        }
        return result;
    }
}

过程如下:

1、 设置参数名称探测器,例如通过它获取方法参数的名称;
2、 如果依赖类型为Optional类型,则调用createOptionalDependency(...)方法,先将descriptor注入表述器封装成NestedDependencyDescriptor对象,底层处理和下面的5.2相同;
3、 否则,如果依赖类型为ObjectFactory或ObjectProvider类型,直接返回一个DependencyObjectProvider私有内部类对象,并没有获取到实例的Bean,需要调用其getObject()方法获取目标对象;
4、 否则,如果依赖类型为javax.inject.Provider类型,直接返回一个Jsr330Provider私有内部类对象,该对象也继承DependencyObjectProvider;
5、 否则,通用的处理逻辑;

1、 先通过AutowireCandidateResolver尝试获取一个代理对象,延迟依赖注入则会返回一个代理对象;
2、 如果上面没有返回代理对象,则进行处理,调用doResolveDependency(...)方法;

我们需要关注的是上面的第 5.2 步所调用 doResolveDependency(...) 方法,这一步是底层实现

2. doResolveDependency 底层处理依赖方法

// DefaultListableBeanFactory.java
@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
        @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

    // 设置当前线程的注入点,并返回上次的注入点,属于嵌套注入的一个保护点
    InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
    try {
        // <1> 针对给定的工厂给定一个快捷实现的方式,暂时忽略
        // 例如考虑一些预先解析的信息,在进入所有 Bean 的常规类型匹配算法之前,解析算法将首先尝试通过此方法解析快捷方式
        Object shortcut = descriptor.resolveShortcut(this);
        if (shortcut != null) {
            // 返回快捷的解析信息
            return shortcut;
        }

        // 依赖的类型
        Class<?> type = descriptor.getDependencyType();
        // <2> 获取注解中的 value 对应的值,例如 @Value、@Qualifier 注解配置的 value 属性值,注意 @Autowired 没有 value 属性配置
        Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
        if (value != null) {
            if (value instanceof String) {
                // <2.1> 解析注解中的 value,因为可能是占位符,需要获取到相应的数据
                String strVal = resolveEmbeddedValue((String) value);
                BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                        getMergedBeanDefinition(beanName) : null);
                value = evaluateBeanDefinitionString(strVal, bd);
            }
            TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
            try {
                // <2.2> 进行类型转换,并返回
                return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
            }
            catch (UnsupportedOperationException ex) {
                // A custom TypeConverter which does not support TypeDescriptor resolution...
                return (descriptor.getField() != null ?
                        converter.convertIfNecessary(value, type, descriptor.getField()) :
                        converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
            }
        }

        // <3> 解析复合的依赖对象(Array、Collection、Map 类型),获取该属性元素类型的 Bean 们
        // 底层和第 4 原理一样,这里会将 descriptor 封装成 MultiElementDescriptor 类型
        Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
        if (multipleBeans != null) {
            return multipleBeans;
        }

        // <4> 查找与类型相匹配的 Bean 们
        // 返回结果:key -> beanName;value -> 对应的 Bean
        Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
        // <5> 如果一个都没找到
        if (matchingBeans.isEmpty()) {
            // <5.1> 如果 @Autowired 配置的 required 为 true,表示必须,则抛出异常
            if (isRequired(descriptor)) {
                raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
            }
            // <5.2> 否则,返回一个空对象
            return null;
        }

        String autowiredBeanName;
        Object instanceCandidate;

        // <6> 如果匹配的 Bean 有多个,则需要找出最优先的那个
        if (matchingBeans.size() > 1) {
            // <6.1> 找到最匹配的那个 Bean,通过 @Primary 或者 @Priority 来决定,或者通过名称决定
            autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
            if (autowiredBeanName == null) {
                if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                    // <6.2> 如果没有找到最匹配的 Bean,则抛出 NoUniqueBeanDefinitionException 异常
                    return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                }
                else {
                    // In case of an optional Collection/Map, silently ignore a non-unique case:
                    // possibly it was meant to be an empty collection of multiple regular beans
                    // (before 4.3 in particular when we didn't even look for collection beans).
                    return null;
                }
            }
            // `<6.3>` 获取到最匹配的 Bean,传值引用给 instanceCandidate
            instanceCandidate = matchingBeans.get(autowiredBeanName);
        }
        // <7> 否则,只有一个 Bean,则直接使用其作为最匹配的 Bean
        else {
            // We have exactly one match.
            Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
            autowiredBeanName = entry.getKey();
            instanceCandidate = entry.getValue();
        }

        // `<8>` 将依赖注入的 Bean 的名称添加至方法入参 autowiredBeanNames 集合,里面保存依赖注入的 beanName
        if (autowiredBeanNames != null) {
            autowiredBeanNames.add(autowiredBeanName);
        }
        // <9> 如果匹配的 Bean 是 Class 对象,则根据其 beanName 依赖查找到对应的 Bean
        if (instanceCandidate instanceof Class) {
            instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
        }
        Object result = instanceCandidate;
        if (result instanceof NullBean) {
            if (isRequired(descriptor)) {
                raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
            }
            result = null;
        }
        if (!ClassUtils.isAssignableValue(type, result)) {
            throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
        }
        // <10> 返回依赖注入的 Bean
        return result;
    }
    finally {
        // 设置当前线程的注入点为上一次的注入点,因为本次注入结束了
        ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
    }
}

依赖处理的过程稍微有点复杂,如下:

1、 针对给定的工厂给定一个快捷实现的方式,暂时忽略;

例如考虑一些预先解析的信息,在进入所有 Bean 的常规类型匹配算法之前,解析算法将首先尝试通过此方法解析快捷方式
2、 获取注解中的value对应的值,例如@Value@Qualifier注解配置的value属性值,注意@Autowired没有value属性配置;

1、 解析注解中的value,因为可能是占位符,需要获取到相应的数据;
2、 进行类型转换,并返回;
3、 解析复合的依赖对象(Array、Collection、Map类型),获取该属性元素类型的Bean们,调用resolveMultipleBeans(...)方法;

底层和下面第 4 步原理一样,这里会将 descriptor 封装成 MultiElementDescriptor 类型,如果找到了则直接返回
4、 查找与类型相匹配的Bean们,调用findAutowireCandidates(...)方法;

返回结果:key -> beanName;value -> 对应的 Bean
5、 如果一个都没找到;

1、 如果@Autowired配置的required为true,表示必须,则抛出异常;
2、 否则,返回一个空对象;
6、 如果匹配的Bean有多个,则需要找出最优先的那个;

1、 找到最匹配的那个Bean,通过@Primary或者@Priority来决定,或者通过名称决定,调用determineAutowireCandidate(...)方法;
2、 如果没有找到最匹配的Bean,则抛出NoUniqueBeanDefinitionException异常;
3、 获取到最匹配的Bean,传值引用给instanceCandidate
7、 否则,只有一个Bean,则直接使用其作为最匹配的Bean;
8、 将依赖注入的Bean的名称添加至方法入参autowiredBeanNames集合,里面保存依赖注入的beanName;
9、 如果匹配的Bean是Class对象,则根据其beanName依赖查找到对应的Bean;
10、 返回依赖注入的Bean;

关于上面第 3 步对于符合依赖对象的处理这里不做详细分析,因为底层和第 4 步一样,接下来分析上面第 46 步所调用的方法

findAutowireCandidates 方法

findAutowireCandidates(@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) 方法,找到符合条件的依赖注入的 Bean 们,如下:

// DefaultListableBeanFactory.java
protected Map<String, Object> findAutowireCandidates(
        @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

    // <1> 从当前上下文找到该类型的 Bean 们(根据类型)
    String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this, requiredType, true, descriptor.isEager());
    // `<2>` 定义一个 Map 对象 result,用于保存符合条件的 Bean
    Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
    /**
     * <3> 遍历 Spring 内部已处理的依赖对象集合,可以跳到 AbstractApplicationContext#prepareBeanFactory 方法中看看
     * 会有一下几个内置处理对象:
     * BeanFactory 类型 -> 返回 DefaultListableBeanFactory
     * ResourceLoader、ApplicationEventPublisher、ApplicationContext 类型 ->  返回 ApplicationContext 对象
     */
    for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
        Class<?> autowiringType = classObjectEntry.getKey();
        if (autowiringType.isAssignableFrom(requiredType)) {
            Object autowiringValue = classObjectEntry.getValue();
            autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
            if (requiredType.isInstance(autowiringValue)) {
                result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
                break;
            }
        }
    }

    // `<4>` 遍历第 1 步找到的 Bean 的名称们
    for (String candidate : candidateNames) {
        // `<4.1>` 如果满足下面两个条件,则添加至 result 集合中
        if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
                && isAutowireCandidate(candidate, descriptor)) { // 符合注入的条件
            addCandidateEntry(result, candidate, descriptor, requiredType);
        }
    }
    // <5> 如果没有找到符合条件的 Bean,则再尝试获取
    if (result.isEmpty()) {
        boolean multiple = indicatesMultipleBeans(requiredType);
        // Consider fallback matches if the first pass failed to find anything...
        DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
        // `<5.1>` 再次遍历第 1 步找到的 Bean 的名称们
        for (String candidate : candidateNames) {
            // `<5.2>` 如果满足下面三个条件,则添加至 result 集合中
            if (!isSelfReference(beanName, candidate) // 如果不是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
                    && isAutowireCandidate(candidate, fallbackDescriptor) // 符合注入的条件
                    && (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) { // 不是复合类型,或者有 @Qualifier 注解
                addCandidateEntry(result, candidate, descriptor, requiredType);
            }
        }
        // <6> 如果还没有找到符合条件的 Bean,则再尝试获取
        // 和上面第 5 步的区别在于必须是自引用(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)
        if (result.isEmpty() && !multiple) {
            // Consider self references as a final pass...
            // but in the case of a dependency collection, not the very same bean itself.
            for (String candidate : candidateNames) {
                if (isSelfReference(beanName, candidate)
                        && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate))
                        && isAutowireCandidate(candidate, fallbackDescriptor)) {
                    addCandidateEntry(result, candidate, descriptor, requiredType);
                }
            }
        }
    }
    // `<7>` 返回 result,符合条件的 Bean
    return result;
}

过程大致如下:

1、 从当前上下文找到该类型的Bean们(根据类型);
2、 定义一个Map对象result,用于保存符合条件的Bean;
3、 遍历Spring内部已处理的依赖对象集合,例如你依赖注入BeanFactory类型的对象,则拿到的是DefaultListableBeanFactory对象,依赖注入ResourceLoader、ApplicationEventPublisher、ApplicationContext类型的对象,拿到的就是当前Spring上下文ApplicationContext对象;
4、 遍历第1步找到的Bean的名称们;

1、 如果满足下面两个条件,则添加至result集合中;

如果**不是自引用**(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)、符合注入的条件

5、 如果没有找到符合条件的Bean,则再尝试获取;

1、 再次遍历第1步找到的Bean的名称们;
2、 如果满足下面三个条件,则添加至result集合中;

如果**不是自引用**(这个 Bean 不是在需要依赖它的 Bean 的内部定义的)、符合注入的条件、不是复合类型,或者有 `@Qualifier` 注解

6、 如果还没有找到符合条件的Bean,则再尝试获取,和上面第5步的区别在于必须是自引用(这个Bean是在需要依赖它的Bean的内部定义的);
7、 返回result,符合条件的Bean;

总结下来:从当前上下文找到所有该类型的依赖注入对象然后返回,注意,如果你依赖注入的对象就是本身这个 Bean 内部定义的对象有特殊处理。

例如注入一个集合对象,元素类型的 Bean 有一个是定义在本身这个 Bean 的内部,如果仅有这个 Bean 则会注入进行;如果除了本身这个 Bean 内部定义了,其他地方也定义了,那么本身这个 Bean 内部定义的 Bean 是不会被注入的;因为是自引用的 Bean 不会优先考虑,除非一个都没找到,才会尝试获取自引用的 Bean

determineAutowireCandidate 方法

determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) 方法,找到最匹配的那个依赖注入对象,如下:

@Nullable
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
    Class<?> requiredType = descriptor.getDependencyType();
    // <1> 尝试获取一个 @Primary 注解标注的 Bean,如果有找到多个则会抛出异常
    String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
    // `<2>` 如果第 1 步找到了则直接返回
    if (primaryCandidate != null) {
        return primaryCandidate;
    }
    // <3> 尝试找到 @Priority 注解优先级最高的那个 Bean,如果存在相同的优先级则会抛出异常
    String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
    // `<4>` 如果第 3 步找到了则直接返回
    if (priorityCandidate != null) {
        return priorityCandidate;
    }
    // Fallback
    // <5> 兜底方法,遍历所有的 Bean
    for (Map.Entry<String, Object> entry : candidates.entrySet()) {
        String candidateName = entry.getKey();
        Object beanInstance = entry.getValue();
        // <5.1> 如果满足下面其中一个条件则直接返回
        if ((beanInstance != null 
            && this.resolvableDependencies.containsValue(beanInstance)) // 该 Bean 为 Spring 内部可处理的 Bean,例如 ApplicationContext
            || matchesBeanName(candidateName, descriptor.getDependencyName())) { // 名称相匹配
            return candidateName;
        }
    }
    // <6> 上面都没选出来则返回一个空对象
    return null;
}

如果找到了多个匹配的依赖注入对象,则需要找到最匹配的那个 Bean,过程大致如下:

1、 尝试获取一个@Primary注解标注的Bean,如果有找到多个则会抛出异常;
2、 如果第1步找到了则直接返回;
3、 尝试找到@Priority注解优先级最高的那个Bean,如果存在相同的优先级则会抛出异常;
4、 如果第3步找到了则直接返回;
5、 兜底方法,遍历所有的Bean;

1、 如果满足下面其中一个条件则直接返回:该Bean为Spring内部可处理的Bean(例如ApplicationContext、BeanFactory)、名称相匹配;
6、 上面都没选出来则返回一个空对象;

总结

@Autowired@Resource 两个注解的区别:

  • 前者是 Spring 注解,后者是 JSR 注解
  • 两个注解都可以通过类型注入 Bean,而后者还可以通过指定名称,通过名称注入对应的 Bean
  • 前者可以通过设置 required 为 false 以支持找不到依赖对象的时候不进行注入,而后者必须找到依赖对象进行注入,找不到则会抛出异常

本文讲述了 @Autowired@Value@Resource 等注解的实现原理,在《Bean 的创建过程》open in new window中我们可以了解到,在 Spring Bean 生命周期的很多阶段都可以通过相应的 BeanPostProcessor 处理器进行扩展,其中《Bean 的属性填充阶段》open in new window会通过 InstantiationAwareBeanPostProcessor 对 Bean 进行处理,有以下两个处理器:

  • AutowiredAnnotationBeanPostProcessor,主要处理 @Autowired 和 @Value 注解进行依赖注入
  • CommonAnnotationBeanPostProcessor,主要处理 @Resource 注解进行依赖注入,以及 @PostConstruct 和 @PreDestroy 生命周期注解的处理

原理就是找到注解标注的字段(或方法),创建对应的注入元信息对象,然后根据该元信息对象进行注入(反射机制),底层都会通过 DefaultListableBeanFactory#resolveDependency 方法实现的,找到符合条件的 Bean(根据类型),然后筛选出最匹配的那个依赖注入对象。

疑问:@Bean 等注解的实现原理又是怎样的呢?别急,在后续文章进行分析

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址:open in new window