Spring @Autowired自動裝配的實現機制
- `@Autowired` 注解實現原理詳解
- 一、`@Autowired` 注解定義
- 二、@Qualifier 注解輔助指定 Bean 名稱
- 三、BeanFactory:按類型獲取 Bean
- 四、注入邏輯實現
- 五、小結
源碼見:mini-spring
@Autowired
注解實現原理詳解
@Autowired
的注入機制與 @Value
注解非常相似,不同之處在于:
-
@Value
主要注入的是常量值或配置項(如${}
表達式); -
而
@Autowired
注入的是 Spring 容器中的 Bean 實例,也即對象引用。
一、@Autowired
注解定義
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
默認情況下,
@Autowired
按類型注入(byType)。如果容器中存在多個相同類型的 Bean,會默認注入第一個;如需精確指定,可以配合@Qualifier
使用。
二、@Qualifier 注解輔助指定 Bean 名稱
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,ElementType.TYPE, ElementType.ANNOTATION_TYPE
})
@Inherited
@Documented
public @interface Qualifier {String value() default "";
}
@Qualifier
允許通過名稱精確指定注入的 Bean,從而避免類型沖突或歧義。
三、BeanFactory:按類型獲取 Bean
為了支持類型注入,我們需要在 BeanFactory
接口中添加一個按類型獲取 Bean 的方法:
/*** 根據指定類型獲取 Bean 實例。* 若存在多個該類型的 Bean,可能拋出異常。*/
<T> T getBean(Class<T> requiredType);
在 DefaultListableBeanFactory
中進行實現:
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {List<String> beanNames = new ArrayList<>();for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {Class<?> beanClass = entry.getValue().getBeanClass();if (requiredType.isAssignableFrom(beanClass)) {beanNames.add(entry.getKey());}}if (beanNames.size() == 1) {return super.getBean(beanNames.get(0), requiredType);}throw new BeansException(requiredType + " expected single bean but found " + beanNames.size() + ": " + beanNames);
}
四、注入邏輯實現
@Autowired
的實現依賴于 Spring 的擴展點 BeanPostProcessor
,更具體地說,是在 InstantiationAwareBeanPostProcessor
接口中重寫的 postProcessPropertyValues
方法完成注入邏輯。
以下是字段注入的核心實現邏輯(簡化版):
for (Field field : declaredFields) {// 檢查是否標注 @AutowiredAutowired autowired = field.getAnnotation(Autowired.class);if (autowired != null) {Class<?> type = field.getType();Object dependentBean;// 優先檢查 @Qualifier 注解Qualifier qualifier = field.getAnnotation(Qualifier.class);if (qualifier != null) {String beanName = qualifier.value();dependentBean = beanFactory.getBean(beanName);} else {// 根據類型獲取 BeandependentBean = beanFactory.getBean(type);}// 直接通過反射注入字段(此處未處理復雜依賴)BeanUtil.setFieldValue(bean, field.getName(), dependentBean);// 原生 Spring 會構建 PropertyValue 并走完整依賴注入流程// pvs.addPropertyValue(new PropertyValue(field.getName(), dependentBean));}
}
本實現簡化了原生 Spring 中的依賴注入邏輯,未處理循環依賴、構造器注入、多候選 Bean 等復雜情況。
五、小結
-
@Autowired
實現基于反射和后置處理器(BeanPostProcessor
); -
默認按類型注入,配合
@Qualifier
可精確按名稱注入; -
實際注入發生在 Bean 實例化之后,屬性填充階段;
-
與
@Value
類似,都通過InstantiationAwareBeanPostProcessor
的postProcessPropertyValues
方法實現。