1. 程式人生 > 其它 >三 Spring 註解 第3.2 之 @Autowire 和 @Resource

三 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的耦合,這樣程式碼看起就比較優雅 。