1. 程式人生 > >Autowired 註解詳解

Autowired 註解詳解

# 前言 我們平時使用 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