注解类org.springframework.context.annotation.Configuration的使用
从Spring3.0,Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
Configuration注解的配置类有如下要求:
- @Configuration不可以是final类型;
- @Configuration不可以是匿名类;
- 嵌套的configuration必须是静态类。
基本使用方法
exp:
1 2 3 4 5 6 7 8
| @Configuration public class AppConfig {
@Bean public MyBean myBean() { } }
|
Configuration标注在类上,相当于把该类作为spring的xml配置文件中的
1 2 3 4 5 6 7 8
| import org.springframework.context.annotation.Configuration;
@Configuration public class AppConfig { public AppConfig() { System.out.println("AppConfig..."); } }
|
相当于
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd" default-lazy-init="false">
</beans>
|
@Bean标注在方法上(返回某个实例的方法),等价于spring的xml配置文件中的,且支持指定初始化和销毁方法
1
| @Bean(name="myBean",initMethod="init",destroyMethod="destroy")
|
总结
- @Configuation等价于
- @Bean等价于
- @ComponentScan等价于<context:component-scan base-package=”com.xxx”/>
注意点
- @Bean注解在返回实例的方法上,如果未通过@Bean指定bean的名称,则默认与标注的方法名相同;
- @Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为原型作用域;
- 既然@Bean的作用是注册bean对象,那么完全可以使用@Component、@Controller、@Service、@Ripository等注解注册bean,当然需要配置@ComponentScan注解进行自动扫描。
加载Configuration class
AnnotationConfigApplicationContext
一般的使用使用AnnotationConfigApplicationContext或其支持web的AnnotationConfigWebApplicationContext来启动:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestMain { public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
} }
|
参考:
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/AnnotationConfigApplicationContext.html
Spring XML
1 2 3 4
| <beans> <context:annotation-config/> <bean class="com.acme.AppConfig"/> </beans>
|
其中<context:annotation-config/>是用来启用ConfigurationClassPostProcessor,由ConfigurationClassPostProcessor来处理@Configuration class
component scanning
@Configuration classes可以和 @ComponentScan 组合使用,指定扫描的Package,生成对应的Bean
1 2 3 4 5
| @Configuration @ComponentScan("com.acme.app.services") public class AppConfig { }
|
PropertySource
使用 @Value 注解,可以使用PropertySource引入配置
1 2 3 4 5 6 7 8 9 10 11
| @Configuration @PropertySource("classpath:/com/acme/app.properties") public class AppConfig {
@Value("${bean.name}") String beanName;
@Bean public MyBean myBean() { return new MyBean(beanName); } }
|
@Import
@Configuration class 可以通过 @Import 注解引入其他 @Configuration class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @Configuration public class DatabaseConfig {
@Bean public DataSource dataSource() { } }
@Configuration @Import(DatabaseConfig.class) public class AppConfig {
private final DatabaseConfig dataConfig;
public AppConfig(DatabaseConfig dataConfig) { this.dataConfig = dataConfig; }
@Bean public MyBean myBean() { return new MyBean(dataConfig.dataSource()); } }
|
@ImportResource
@Configuration class 可以通过 @ImportResource 导入其他xml配置。
1 2 3 4 5 6 7 8 9 10 11 12
| @Configuration @ImportResource("classpath:/com/acme/database-config.xml") public class AppConfig {
@Inject DataSource dataSource;
@Bean public MyBean myBean() { return new MyBean(this.dataSource); } }
|
nested @Configuration classes
Configuration class允许嵌套
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Configuration public class AppConfig {
@Inject DataSource dataSource;
@Bean public MyBean myBean() { return new MyBean(dataSource); }
@Configuration static class DatabaseConfig { @Bean DataSource dataSource() { return new EmbeddedDatabaseBuilder().build(); } } }
|
注意,嵌套的 Configuration class必须是 静态类
@Lazy
可以使用@Lazy懒初始化Bean, @Lazy放在Configuration class上会使其所有定义的Bean懒初始化,@Lazy也可以放在@Bean方法上单独使用。
testing
需要spring-test模块的@ContextConfiguration注解来获取Configuration Class 数组。
1 2 3 4 5 6 7 8 9 10 11 12 13
| @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes={AppConfig.class, DatabaseConfig.class}) public class MyTests {
@Autowired MyBean myBean;
@Autowired DataSource dataSource;
@Test public void test() { } }
|
参考资料
https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html
https://www.cnblogs.com/duanxz/p/7493276.html