詳解Java如何使用注解來(lái)配置Spring容器
介紹
我們將介紹如何在Java代碼中使用注解來(lái)配置Spring容器。它包括:
- Basic Concepts: @Bean and @Configuration。
- Instantiating the Spring Container by Using 。
- AnnotationConfigApplicationContext。
- Using the @Bean Annotation。
- Using the @Configuration annotation。
- Composing Java-based Configurations。
- Bean Definition Profiles。
- PropertySource Abstraction。
- Using @PropertySource。
- Placeholder Resolution in Statements。
@Bean and @Configuration
@Bean注解用在一個(gè)方法上表示實(shí)例化、配置和初始化一個(gè)新對(duì)象,由Spring IoC容器管理。對(duì)于那些熟悉Spring的 XML配置的人來(lái)說(shuō),@Bean注解的作用與元素的作用相同。
用@Configuration來(lái)注解一個(gè)類(lèi),表明它的主要目的是作為一個(gè)bean定義的來(lái)源。此外,@Configuration類(lèi)允許通過(guò)調(diào)用同一個(gè)類(lèi)中的其他@Bean方法來(lái)定義Bean間的依賴(lài)關(guān)系。最簡(jiǎn)單的@Configuration類(lèi)如下:
@Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } @Bean public OtherService otherService() { return new OtherService(); } }
AnnotationConfigApplicationContext實(shí)例化容器
與實(shí)例化
ClassPathXmlApplicationContext時(shí)使用Spring XML文件作為輸入的方式相同,你可以在實(shí)例化AnnotationConfigApplicationContext時(shí)使用@Configuration類(lèi)作為輸入。這使得Spring容器的使用完全不需要XML,如下例子:
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); MyService myService = ctx.getBean(MyService.class); myService.doStuff(); }
通過(guò)使用 register(Class...) 以編程方式構(gòu)建容器
你可以通過(guò)使用無(wú)參數(shù)構(gòu)造函數(shù)來(lái)實(shí)例化AnnotationConfigApplicationContext,然后使用 register() 方法來(lái)配置它。這種方法在以編程方式構(gòu)建 AnnotationConfigApplicationContext 時(shí)特別有用。下面的例子展示了如何做到這一點(diǎn)。
public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class, OtherConfig.class); ctx.register(AdditionalConfig.class); ctx.refresh(); MyService myService = ctx.getBean(MyService.class); myService.doStuff(); }
@ComponentScan啟用組件掃描
為了啟用組件掃描,可以在@Configuration類(lèi)做如下注釋。
@Configuration @ComponentScan(basePackages = "com.acme") public class AppConfig { // ... }
Bean的依賴(lài)
@Configuration public class AppConfig { @Bean public TransferService transferService(AccountRepository accountRepository) { return new TransferServiceImpl(accountRepository); } }
生命周期回調(diào)
任何用@Bean注解定義的類(lèi)都支持常規(guī)的生命周期回調(diào),并且可以使用JSR-250的@PostConstruct和@PreDestroy注解。如果一個(gè)bean實(shí)現(xiàn)了InitializingBean、DisposableBean或Lifecycle,它們各自的方法將被容器調(diào)用。
public class BeanOne { public void init() { // initialization logic } } public class BeanTwo { public void cleanup() { // destruction logic } } @Configuration public class AppConfig { @Bean(initMethod = "init") public BeanOne beanOne() { return new BeanOne(); } @Bean(destroyMethod = "cleanup") public BeanTwo beanTwo() { return new BeanTwo(); } }
Bean指定作用域
Bean默認(rèn)的作用域是singleton,更多Bean作用域可參考Bean作用域章節(jié)。
@Configuration public class MyConfiguration { @Bean @Scope("prototype") public Encryptor encryptor() { // ... } }
自定義bean名稱(chēng)
默認(rèn)情況下,配置類(lèi)使用@Bean方法的名稱(chēng)作為Bean的名稱(chēng)。可以通過(guò)name屬性來(lái)自定義名稱(chēng),如下:
@Configuration public class AppConfig { @Bean("myThing") public Thing thing() { return new Thing(); } }
Bean別名
@Configuration public class AppConfig { @Bean({"dataSource", "subsystemA-dataSource", "subsystemB-dataSource"}) public DataSource dataSource() { // instantiate, configure and return DataSource bean... } }
Bean注入之間的依賴(lài)
@Configuration public class AppConfig { @Bean public BeanOne beanOne() { return new BeanOne(beanTwo()); } @Bean public BeanTwo beanTwo() { return new BeanTwo(); } }
@Import
@Import注解表示要導(dǎo)入一個(gè)或多個(gè)@Configuration類(lèi)。在導(dǎo)入的@Configuration類(lèi)中聲明的@Bean定義應(yīng)該通過(guò)使用@Autowired注入來(lái)訪(fǎng)問(wèn)。
@Configuration public class ConfigA { @Bean public A a() { return new A(); } } @Configuration @Import(ConfigA.class) public class ConfigB { @Bean public B b() { return new B(); } }
現(xiàn)在,在實(shí)例化上下文時(shí)不需要同時(shí)指定ConfigA類(lèi)和ConfigB類(lèi),而只需要明確提供ConfigB:
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class); // now both beans A and B will be available... A a = ctx.getBean(A.class); B b = ctx.getBean(B.class); }
@ImportResource
Spring提供了一個(gè)@ImportResource注解,用于從applicationContext.xml文件中加載bean到應(yīng)用上下文中。
@Configuration @ImportResource("classpath:/com/acme/properties-config.xml") public class AppConfig { @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean public DataSource dataSource() { return new DriverManagerDataSource(url, username, password); } }
<!-- properties-config.xml --> <beans> <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/> </beans>
@PropertySource
我們將討論如何使用@PropertySource來(lái)讀取屬性文件,并用@Value和Environment來(lái)顯示值。
@PropertySource注解為向Spring的環(huán)境添加PropertySource提供了一種方便的聲明性機(jī)制。要與@Configuration類(lèi)一起使用。
假設(shè)我們從config.properties文件中讀取數(shù)據(jù)庫(kù)配置,并使用Environment將這些屬性值設(shè)置為DataSourceConfig類(lèi)。
@Configuration @PropertySource("classpath:config.properties") public class ProperySourceDemo implements InitializingBean { @Autowired Environment env; @Override public void afterPropertiesSet() throws Exception { setDatabaseConfig(); } private void setDatabaseConfig() { DataSourceConfig config = new DataSourceConfig(); config.setDriver(env.getProperty("jdbc.driver")); config.setUrl(env.getProperty("jdbc.url")); config.setUsername(env.getProperty("jdbc.username")); config.setPassword(env.getProperty("jdbc.password")); System.out.println(config.toString()); } }
支持多個(gè)properties文件
@Configuration @PropertySources({ @PropertySource("classpath:config.properties"), @PropertySource("classpath:db.properties") }) public class AppConfig { //... }
ApplicationContext
ApplicationContext實(shí)現(xiàn)了BeanFactory接口,并提供了如下功能:
- 通過(guò)MessageSource接口,訪(fǎng)問(wèn)i18n風(fēng)格的消息。
- 通過(guò)ResourceLoader接口訪(fǎng)問(wèn)資源,如URL和文件。
- 事件發(fā)布,即通過(guò)使用ApplicationEventPublisher接口,向?qū)崿F(xiàn)ApplicationListener接口的bean發(fā)布。
- 通過(guò)HierarchicalBeanFactory接口加載多個(gè)(分層的)上下文,讓每個(gè)上下文專(zhuān)注于一個(gè)特定的層,例如一個(gè)應(yīng)用程序的Web層。
MessageSource 國(guó)際化
ApplicationContext接口擴(kuò)展了一個(gè)名為MessageSource的接口,因此,它提供了國(guó)際化("i18n")功能。Spring還提供了HierarchicalMessageSource接口,它可以分層次地解析消息。
account.name=TestAccount
@Configuration public class AppConfig { @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("config/messages"); return messageSource; } }
@Service public class AccountService { @Autowired private MessageSource messageSource; public void someMsg() { messageSource.getMessage("account.name", null, Locale.ENGLISH); //todo } }
以上就是詳解Java如何使用注解來(lái)配置Spring容器的詳細(xì)內(nèi)容,更多關(guān)于Java注解配置Spring容器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
idea mac版打開(kāi)是出現(xiàn)打開(kāi)失敗問(wèn)題及解決
這篇文章主要介紹了idea mac版打開(kāi)是出現(xiàn)打開(kāi)失敗問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09idea遠(yuǎn)程調(diào)試spark的步驟講解
今天小編就為大家分享一篇關(guān)于idea遠(yuǎn)程調(diào)試spark的步驟講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03Spring.Net在MVC中實(shí)現(xiàn)注入的原理解析
這篇文章主要介紹了Spring.Net在MVC中實(shí)現(xiàn)注入的原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09Java定時(shí)器通信協(xié)議管理模塊Timer詳解
這篇文章主要介紹了Java定時(shí)器通信協(xié)議管理模塊Timer,?Timer一般指定時(shí)器(通信協(xié)議管理模塊)人類(lèi)最早使用的定時(shí)工具是沙漏或水漏,但在鐘表誕生發(fā)展成熟之后,人們開(kāi)始嘗試使用這種全新的計(jì)時(shí)工具來(lái)改進(jìn)定時(shí)器,達(dá)到準(zhǔn)確控制時(shí)間的目的2022-08-08Java編程中實(shí)現(xiàn)Condition控制線(xiàn)程通信
這篇文章主要介紹了Java編程中實(shí)現(xiàn)Condition控制線(xiàn)程通信,簡(jiǎn)單介紹了Java中控制線(xiàn)程通信的方法,以及對(duì)condition的解析和實(shí)例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11springboot?注解方式批量插入數(shù)據(jù)的實(shí)現(xiàn)
一次請(qǐng)求需要往數(shù)據(jù)庫(kù)插入多條數(shù)據(jù)時(shí),可以節(jié)省大量時(shí)間,本文主要介紹了springboot?注解方式批量插入數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Java Agent入門(mén)學(xué)習(xí)之動(dòng)態(tài)修改代碼
這篇文章主要給大家分享了Java Agent入門(mén)學(xué)習(xí)之動(dòng)態(tài)修改代碼的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-07-07springcloud集成nacos?使用lb?無(wú)效問(wèn)題解決方案
這篇文章主要介紹了解決springcloud集成nacos?使用lb?無(wú)效,通過(guò)查看spring-cloud-starter-gateway?jar中的自動(dòng)配置類(lèi)的源碼,得知,該jar包中是不支持負(fù)載均衡的,需要引入spring-cloud-starter-loadbalancer?來(lái)支持,需要的朋友可以參考下2023-04-04Mybatis查詢(xún)語(yǔ)句返回對(duì)象和泛型集合的操作
這篇文章主要介紹了Mybatis查詢(xún)語(yǔ)句返回對(duì)象和泛型集合的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07