javascript
Spring5参考指南:基于注解的容器配置
文章目錄
- @Required
- @Autowired
- @primary
- @Qualifier
- 泛型
- @Resource
- @PostConstruct和@PreDestroy
Spring的容器配置可以有兩種方式,一種基于XML文件, 一種基于注解。注解注入在XML注入之前執行。因此,當兩個同時使用時,XML配置會覆蓋注解注入的屬性。
本文會主要介紹 @Required,@Autowired, @PostConstruct, @PreDestroy 和 @Resource 這幾個注解。
這幾個注解都是由 context:annotation-config/ 來引入的。本質上引入這個配置會隱式的注冊AutoWiredAnnotationBeanPostProcessor(提供@Autowired),CommonAnnotationBeanPostProcessor(提供@PostConstruct, @PreDestroy, @Resource),RequiredAnnotationBeanPostProcessor(提供 @Required),從而提供各個注解的功能。
下面我們會分別介紹各個注解的功能。
@Required
@Required 一般用在方法上面,表示該方法的參數必須能通過配置或者自動裝載來填充。通常如果某個屬性是必須的,我們會使用這個注解。
不過從Spring Framework 5.1開始,@Required注解正式被棄用,取而代之的是使用構造函數注入用于所需的屬性,或使用InitializingBean.afterPropertiesSet()的自定義實現以及bean屬性setter方法。
示例代碼如下:
public class RequiredBean {private BeanA beanA;@Requiredpublic void setBeanA(BeanA beanA){this.beanA=beanA;} }@Autowired
@Autowired 就是自動注入所需要的字段,參數等。JSR 330的@Inject注解可以代替spring的@Autowired注解。
你可以將@Autowired注解到構造器中,如下所示:
public class AutowiredBean {private BeanA beanA;@Autowiredpublic AutowiredBean(BeanA beanA){this.beanA=beanA;} }從SpringFramework4.3開始,如果目標bean只定義了一個構造函數,那么就不再需要在此類構造函數上使用@Autowired注解。但是,如果有多個構造函數可用,則必須至少對其中一個進行注解,以告訴容器使用哪一個。
@Autowired也可以注解到傳統的setter方法,如下例子所示:
public class AutowiredBean {private BeanB beanB;@Autowiredpublic void setBeanB(BeanB beanB){this.beanB=beanB;} }也可以把注解應用到任何名字和多個參數,如下所示:
@Autowiredpublic void configAB(BeanA beanA , BeanB beanB){this.beanA=beanA;this.beanB=beanB;}@Autowired也可以用在字段上,如下所示:
@Autowiredprivate BeanC beanC;還可以通過將注解添加到需要該類型數組的字段或方法,那么可以從ApplicationContext中獲取到該特定類型的所有bean,如下例所示:
@Autowiredprivate BeanC[] beanCList;如果希望數組或列表中的項按特定順序排序,目標bean可以實現org.springframework.core.Ordered接口,或者可以使用@Order或標準的@Priority注解。
否則,它們的順序遵循容器中相應目標bean定義的注冊順序。
Map實例也可以被注入,只要key是String類型。Map value包括了所有的類型匹配的Bean,keys是該bean的名字。如下所示:
@Autowiredpublic void configMapA(Map<String,BeanA> mapA){this.mapA=mapA;}@Autowired有個required屬性,如果要注入的bean有可能不存在,則可以如下所示:
@Autowired(required = false)public void setBeanC(BeanC beanC){}建議使用@Autowired的’required’屬性而不是使用setter方法上的@Required注解?!皉equired”屬性表示自動裝載需要該屬性, 如果無法自動裝載,則忽略該屬性。而對于@Required來說,如果未定義任何值,則會報異常。
也可以通過Java 8的java.util.Optional表示特定依賴項的非必需性質,如下示例顯示:
@Autowiredpublic void setMovieFinder(Optional<BeanC> BeanC) {}在Spring Framework 5.0中,你也可以使用@Nullable注解:
@Autowiredpublic void setMovieFinderC(@Nullable BeanC beanC) {}Spring可以使用@Autowired來自動解析一些默認存在的bean如:BeanFactory、ApplicationContext、Environment、ResourceLoader、ApplicationEventPublisher和MessageSource。這些接口及其擴展接口(如ConfigurableApplicationContext或ResourcePatternResolver)。
如下所示,自動注入ApplicationContext:
注意: @Autowired, @Inject, @Value, 和 @Resource 注解是在Spring的BeanPostProcessor中處理的,這意味著你不能將這些注解用在你自己的BeanPostProcessor,BeanFactoryPostProcessor類型。
@primary
當按類型注入的時候,可能會有多個候選項,則可以通過@Primary注解表示優先的對象。如下所示:
@Configuration public class ConfigBean {@Bean@Primarypublic BeanA firstBeanA() { return new BeanA(); }@Beanpublic BeanA secondBeanA() { return new BeanA();}}@Qualifier
@Primary是一種在多個實例中按類型使用自動裝載的有效方法,但是如果你希望對注入的Bean進行更細粒度的控制時候,可以使用@Qualifier。如下所示:
@Bean@Qualifier("main")public BeanC beanC() { return new BeanC();} @Autowired@Qualifier("main")private BeanA beanA;@Autowiredpublic void setBeanA(@Qualifier("main") BeanA beanA){}限定符的值并不是唯一的,它只是一個過濾標準。
@Autowired一般用來通過類型匹配,@Resource則是通過名稱匹配。
也可以創建自定義注解:
@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface Genre {String value(); }泛型
除了@Qualifier注解外,還可以使用Java泛型類型作為隱式的限定形式。例如,假設您具有以下配置:
public class StringStore implements Store<String> { }public class IntegerStore implements Store<Integer> { } @Beanpublic StringStore stringStore() {return new StringStore();}@Beanpublic IntegerStore integerStore() {return new IntegerStore();} public class GenericBean {@Autowiredprivate Store<String> s1; // <String> qualifier, injects the stringStore bean@Autowiredprivate Store<Integer> s2; // <Integer> qualifier, injects the integerStore bean// Inject all Store beans as long as they have an <Integer> generic// Store<String> beans will not appear in this list@Autowiredprivate List<Store<Integer>> s;}@Resource
@Resource用在字段或者Setter方法上,默認情況下@Resource通過名字來注入。
public class ResourceBean {@Resource(name = "beanA")private BeanA BeanA; }如果未顯式指定名稱,則從字段名或setter方法派生默認名稱.
在@Resource用法中,如果沒有指定顯式名稱,并且類似于@Autowired,@Resource會找到一個主類型匹配,而不是指定的bean,并解析已知的可解析依賴項:BeanFactory、ApplicationContext、ResourceLoader、ApplicationEventPublisher,和MessageSource接口。
@PostConstruct和@PreDestroy
這兩個注解主要用做生命周期回調。如下所示:
public class ConstructBean {@PostConstructpublic void populateMovieCache() {// populates the movie cache upon initialization...}@PreDestroypublic void clearMovieCache() {// clears the movie cache upon destruction...} }與@Resource一樣,@PostConstruct和@PreDestroy注解類型是JDK 6到8標準Java庫的一部分。然而,整個javax.annotation包與JDK 9中的核心Java模塊分離,并最終在JDK 11中被刪除。如果需要,javax.annotation-api工件現在需要通過maven central獲得,只需像其他庫一樣添加到應用程序的類路徑中即可。
本文的代碼可以參考annotation-config
更多精彩內容且看:
- 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
- Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
- Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
- java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程
更多教程請參考flydean的博客
總結
以上是生活随笔為你收集整理的Spring5参考指南:基于注解的容器配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring5参考指南:容器扩展
- 下一篇: gradle idea java ssm