詳解Java如何使用注解來配置Spring容器
介紹
我們將介紹如何在Java代碼中使用注解來配置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配置的人來說,@Bean注解的作用與元素的作用相同。
用@Configuration來注解一個(gè)類,表明它的主要目的是作為一個(gè)bean定義的來源。此外,@Configuration類允許通過調(diào)用同一個(gè)類中的其他@Bean方法來定義Bean間的依賴關(guān)系。最簡單的@Configuration類如下:
@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類作為輸入。這使得Spring容器的使用完全不需要XML,如下例子:
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}通過使用 register(Class...) 以編程方式構(gòu)建容器
你可以通過使用無參數(shù)構(gòu)造函數(shù)來實(shí)例化AnnotationConfigApplicationContext,然后使用 register() 方法來配置它。這種方法在以編程方式構(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類做如下注釋。
@Configuration
@ComponentScan(basePackages = "com.acme")
public class AppConfig {
// ...
}Bean的依賴
@Configuration
public class AppConfig {
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
}生命周期回調(diào)
任何用@Bean注解定義的類都支持常規(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名稱
默認(rèn)情況下,配置類使用@Bean方法的名稱作為Bean的名稱??梢酝ㄟ^name屬性來自定義名稱,如下:
@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注入之間的依賴
@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類。在導(dǎo)入的@Configuration類中聲明的@Bean定義應(yīng)該通過使用@Autowired注入來訪問。
@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類和ConfigB類,而只需要明確提供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來讀取屬性文件,并用@Value和Environment來顯示值。
@PropertySource注解為向Spring的環(huán)境添加PropertySource提供了一種方便的聲明性機(jī)制。要與@Configuration類一起使用。
假設(shè)我們從config.properties文件中讀取數(shù)據(jù)庫配置,并使用Environment將這些屬性值設(shè)置為DataSourceConfig類。
@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接口,并提供了如下功能:
- 通過MessageSource接口,訪問i18n風(fēng)格的消息。
- 通過ResourceLoader接口訪問資源,如URL和文件。
- 事件發(fā)布,即通過使用ApplicationEventPublisher接口,向?qū)崿F(xiàn)ApplicationListener接口的bean發(fā)布。
- 通過HierarchicalBeanFactory接口加載多個(gè)(分層的)上下文,讓每個(gè)上下文專注于一個(gè)特定的層,例如一個(gè)應(yīng)用程序的Web層。
MessageSource 國際化
ApplicationContext接口擴(kuò)展了一個(gè)名為MessageSource的接口,因此,它提供了國際化("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如何使用注解來配置Spring容器的詳細(xì)內(nèi)容,更多關(guān)于Java注解配置Spring容器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringCloud?@RefreshScope刷新機(jī)制淺析
RefeshScope這個(gè)注解想必大家都用過,在微服務(wù)配置中心的場景下經(jīng)常出現(xiàn),他可以用來刷新Bean中的屬性配置,那大家對(duì)他的實(shí)現(xiàn)原理了解嗎?它為什么可以做到動(dòng)態(tài)刷新呢2023-03-03
SpringBoot 策略模式實(shí)現(xiàn)切換上傳文件模式
策略模式是指有一定行動(dòng)內(nèi)容的相對(duì)穩(wěn)定的策略名稱,這篇文章主要介紹了SpringBoot 策略模式 切換上傳文件模式,需要的朋友可以參考下2023-11-11
IDEA查看所有的斷點(diǎn)(Breakpoints)并關(guān)閉的方式
我們?cè)谑褂肐DEA開發(fā)Java應(yīng)用時(shí),基本上都需要進(jìn)行打斷點(diǎn)的操作,這方便我們排查BUG,也方便我們查看設(shè)計(jì)的是否正確,不過有時(shí)候,我們不希望進(jìn)入斷點(diǎn),所以我們需要快速關(guān)閉所有斷點(diǎn),故本文給大家介紹了IDEA查看所有的斷點(diǎn)(Breakpoints)并關(guān)閉的方式2024-10-10
SpringCloud Eureka服務(wù)的基本配置和操作方法
Eureka是Netflix開源的一個(gè)基于REST的服務(wù)治理框架,主要用于實(shí)現(xiàn)微服務(wù)架構(gòu)中的服務(wù)注冊(cè)與發(fā)現(xiàn),Eureka是Netflix開源的服務(wù)發(fā)現(xiàn)框架,用于在分布式系統(tǒng)中實(shí)現(xiàn)服務(wù)的自動(dòng)注冊(cè)與發(fā)現(xiàn),本文介紹SpringCloud Eureka服務(wù)的基本配置和操作方法,感興趣的朋友一起看看吧2023-12-12
Mybatis中使用萬能的Map傳參實(shí)現(xiàn)
在編程中,有可能遇到我們的實(shí)體類或者數(shù)據(jù)庫中表的字段或參數(shù)過多的情況,那這時(shí)候用Map傳參是比較理想的選擇,本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解下2021-07-07
IDEA報(bào)java:?java.lang.OutOfMemoryError:?Java?heap?space錯(cuò)誤
這篇文章主要給大家介紹了關(guān)于IDEA報(bào)java:?java.lang.OutOfMemoryError:?Java?heap?space錯(cuò)誤的解決辦法,文中將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
SpringBoot處理form-data表單接收對(duì)象數(shù)組的方法
form-data則是一種更加靈活的編碼方式,它可以處理二進(jìn)制數(shù)據(jù)(如圖片、文件等)以及文本數(shù)據(jù),這篇文章主要介紹了SpringBoot處理form-data表單接收對(duì)象數(shù)組,需要的朋友可以參考下2023-11-11
Java數(shù)據(jù)結(jié)構(gòu)之查找
本文主要介紹了Java數(shù)據(jù)結(jié)構(gòu)中查找的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-03-03

