三 Spring 註解 第3.2 之 @Autowire 和 @Resource
三 Spring 註解
第3.2 之 @Autowire 和 @Resource
@Autowired 或 @Resource 可修飾變數\方法\建構函式,用於完成自動裝配(將需要的外部資源注入)
@Autowired Class_A a : 預設按照型別byType
Qualifier和Autowired配合使用,可以指定bean的byname 只包含一個:required,預設true開啟自動准入,依賴物件必須存在,若要允許null值,改為flase 用在 構造器、方法、引數、成員變數和註解上 spring定義的註解 AutoWiredAnnotationBeanPostProcessor是處理@AutoWired註解的 @Resource Class_A a: 預設用來指定名稱byname注入 包含七個引數,其中最重要的兩個引數是:name 和 type。 用在:類、成員變數和方法上 @Resource是JDK定義的註解 CommonAnnotationBeanPostProcessor是處理@ReSource註解的 @Resource的匹配邏輯為byName -> byType -> byName 有多個bean時,可以在Class_A 上增加@Primary 優先裝配A,來避免匹配失敗
3.2.1 @Autowire
-
@Autowired裝配失敗,裝配的物件還是null
原因:
① 類上面忘了加@Component(@Service、@Repository @Controller) @Configuration等註解,spring就無法完成自動裝配的功能
② 註解未被@ComponentScan掃描 ,或者@ComponentScan註解掃描的路徑不對
③ 注入Filter或Listener
(web應用啟動的順序是:listener->filter->servlet)
springmvc的啟動是在DisptachServlet裡面做的,而它是在listener和filter之後執行。若在listener和filter裡面
@Autowired某個bean時bean還沒有初始化,無法自動裝配 -
作用範圍 成員變數\構造器\set 方法\構造器入參\非靜態方法入參
1 成員變數在成員變數上使用Autowired註解: @Service public class UserService { @Autowired private IUser user; }這種方式可能是平時用得最多的。4.2 構造器在構造器上使用Autowired註解:@Service public class UserService { private IUser user; @Autowired public UserService(IUser user) { this.user = user; System.out.println("user:" + user); } }注意,在構造器上加Autowired註解,實際上還是使用了Autowired裝配方式,並非構造器裝配。4.3 方法在普通方法上加Autowired註解:@Service public class UserService { @Autowired public void test(IUser user) { user.say(); } }spring會在專案啟動的過程中,自動呼叫一次加了@Autowired註解的方法,我們可以在該方法做一些初始化的工作。也可以在setter方法上Autowired註解: @Service public class UserService { private IUser user; @Autowired public void setUser(IUser user) { this.user = user; } }4.4 引數可以在構造器的入參上加Autowired註解:@Service public class UserService { private IUser user; public UserService(@Autowired IUser user) { this.user = user; System.out.println("user:" + user); } } 也可以在非靜態方法的入參上加Autowired註解:@Service public class UserService { public void test(@Autowired IUser user) { user.say(); } } 4.5 用在註解上 4.6 自動裝配預設都是單個例項 Autowired 實現自動裝配多個例項 UserService方法調整一下,用一個List集合接收IUser型別的引數: @Service public class UserService { @Autowired private List<IUser> userList; @Autowired private Set<IUser> userSet; @Autowired private Map<String, IUser> userMap; public void test() { System.out.println("userList:" + userList); System.out.println("userSet:" + userSet); System.out.println("userMap:" + userMap); } }增加一個controller:@RequestMapping("/u") @RestController public class UController { @Autowired private UserService userService; @RequestMapping("/test") public String test() { userService.test(); return "success"; } }
3.2.2 @Resource
@Resource裝配順序
1. 如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則丟擲異常
2. 如果指定了name,則從上下文中查詢名稱(id)匹配的bean進行裝配,找不到則丟擲異常
3. 如果指定了type,則從上下文中找到型別匹配的唯一bean進行裝配,找不到或者找到多個,都會丟擲異常
4. 如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始型別進行匹配,如果匹配則自動裝配;推薦使用@Resource註解在欄位上,這樣就不用寫setter方法了.並且這個註解是屬於J2EE的,減少了與Spring的耦合,這樣程式碼看起就比較優雅 。