Autowired 註解詳解
阿新 • • 發佈:2020-06-11
# 前言
我們平時使用 Spring 時,想要 **依賴注入** 時使用最多的是 `@Autowired` 註解了,本文主要講解 Spring 是如何處理該註解並實現 **依賴注入** 的功能的。
# 正文
首先我們看一個測試用例:
`User` 實體類:
```java
public class User {
private Long id;
private String name;
// 省略 get 和 set 方法
}
```
測試類:
```java
public class AnnotationDependencyInjectTest {
/**
* @Autowired 欄位注入
*/
@Autowired
private User user;
private City city;
/**
* @Autowired 方法注入
*/
@Autowired
public void initCity(City city) {
this.city = city;
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(AnnotationDependencyInjectTest.class);
context.refresh();
AnnotationDependencyInjectTest bean = context.getBean(AnnotationDependencyInjectTest.class);
// @Autowired 欄位注入
System.out.println(bean.user);
// @Autowired 方法注入
System.out.println(bean.city);
UserHolder userHolder = context.getBean(UserHolder.class);
// @Autowired 構造器注入
System.out.println(userHolder.getUser());
context.close();
}
@Bean
public User user() {
User user = new User();
user.setId(1L);
user.setName("leisurexi");
return user;
}
@Bean
public City city() {
City city = new City();
city.setId(1L);
city.setName("北京");
return city;
}
/**
* @Autowired 建構函式注入
*/
static class UserHolder {
private User user;
@Autowired
public UserHolder(User user) {
this.user = user;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
}
```
上面分別展示了 `@Autowired` 註解的欄位注入和方法注入,下面我們開始分析 Spring 是如何實現的。
首先使 `@Autowired` 註解生效的一個關鍵類是 `AutowiredAnnotationBeanPostProcessor`,該類實現了 `InstantiationAwareBeanPostProcessorAdapter` 抽象類;該抽象類就是一個介面卡的作用提供了介面方法的預設實現,`InstantiationAwareBeanPostProcessorAdapter` 又實現了 `SmartInstantiationAwareBeanPostProcessor` 介面,同時實現該介面的 `determineCandidateConstructors()` 方法可以指定 `bean` 的候選建構函式;然後 `SmartInstantiationAwareBeanPostProcessor` 介面又繼承了 `InstantiationAwareBeanPostProcessor` 介面,該介面提供了 `bean` 例項化前後的生命週期回撥以及屬性賦值前的後置處理方法,`@Autowired` 註解的屬性注入就是通過重寫該介面的 `postProcessProperties()` 實現的。這兩個介面都在 在 [Spring IoC createBean 方法詳解](https://www.cnblogs.com/yijinqincai/p/12931056.html) 一文中有介紹過。下面我們看一下 `AutowiredAnnotationBeanProcessor` 的繼承關係圖:
![](http://ww1.sinaimg.cn/large/006Vpl27gy1gfjts4v6uqj30x70dvt9g.jpg)
關於 `AutowiredAnnotationBeanPostProcessor` 這個後置處理器是怎麼加入到 `beanFactory` 中的,我們在 [Spring IoC component-scan 節點詳解](https://www.cnblogs.com/yijinqincai/p/12995298.html) 一文中介紹過主要是通過 `AnnotationConfigUtils#registerAnnotationConfigProcessors()` 實現的。
```java
public st