詳解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註解用在一個方法上表示實例化、配置和初始化一個新對象,由Spring IoC容器管理。對於那些熟悉Spring的 XML配置的人來說,@Bean註解的作用與元素的作用相同。
用@Configuration來註解一個類,表明它的主要目的是作為一個bean定義的來源。此外,@Configuration類允許通過調用同一個類中的其他@Bean方法來定義Bean間的依賴關系。最簡單的@Configuration類如下:
@Configuration public class AppConfig { @Bean public MyService myService() { return new MyServiceImpl(); } @Bean public OtherService otherService() { return new OtherService(); } }
AnnotationConfigApplicationContext實例化容器
與實例化
ClassPathXmlApplicationContext時使用Spring XML文件作為輸入的方式相同,你可以在實例化AnnotationConfigApplicationContext時使用@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…) 以編程方式構建容器
你可以通過使用無參數構造函數來實例化AnnotationConfigApplicationContext,然後使用 register() 方法來配置它。這種方法在以編程方式構建 AnnotationConfigApplicationContext 時特別有用。下面的例子展示瞭如何做到這一點。
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); } }
生命周期回調
任何用@Bean註解定義的類都支持常規的生命周期回調,並且可以使用JSR-250的@PostConstruct和@PreDestroy註解。如果一個bean實現瞭InitializingBean、DisposableBean或Lifecycle,它們各自的方法將被容器調用。
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默認的作用域是singleton,更多Bean作用域可參考Bean作用域章節。
@Configuration public class MyConfiguration { @Bean @Scope("prototype") public Encryptor encryptor() { // ... } }
自定義bean名稱
默認情況下,配置類使用@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註解表示要導入一個或多個@Configuration類。在導入的@Configuration類中聲明的@Bean定義應該通過使用@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(); } }
現在,在實例化上下文時不需要同時指定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提供瞭一個@ImportResource註解,用於從applicationContext.xml文件中加載bean到應用上下文中。
@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的環境添加PropertySource提供瞭一種方便的聲明性機制。要與@Configuration類一起使用。
假設我們從config.properties文件中讀取數據庫配置,並使用Environment將這些屬性值設置為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()); } }
支持多個properties文件
@Configuration @PropertySources({ @PropertySource("classpath:config.properties"), @PropertySource("classpath:db.properties") }) public class AppConfig { //... }
ApplicationContext
ApplicationContext實現瞭BeanFactory接口,並提供瞭如下功能:
- 通過MessageSource接口,訪問i18n風格的消息。
- 通過ResourceLoader接口訪問資源,如URL和文件。
- 事件發佈,即通過使用ApplicationEventPublisher接口,向實現ApplicationListener接口的bean發佈。
- 通過HierarchicalBeanFactory接口加載多個(分層的)上下文,讓每個上下文專註於一個特定的層,例如一個應用程序的Web層。
MessageSource 國際化
ApplicationContext接口擴展瞭一個名為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容器的詳細內容,更多關於Java註解配置Spring容器的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Spring純註解開發模式讓開發簡化更簡化
- 帶你快速入門掌握Spring的那些註解使用
- SpringBoot隨機數設置及參數間引用的操作步驟
- Spring中如何使用@Value註解實現給Bean屬性賦值
- 關於@Configuration的作用說明