Hello World

吞风吻雨葬落日 欺山赶海踏雪径

0%

Spring Configuration注解的使用

注解类org.springframework.context.annotation.Configuration的使用

从Spring3.0,Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContextAnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

Configuration注解的配置类有如下要求:

  • @Configuration不可以是final类型;
  • @Configuration不可以是匿名类;
  • 嵌套的configuration必须是静态类。

基本使用方法

exp:

1
2
3
4
5
6
7
8
@Configuration
public class AppConfig {

@Bean
public MyBean myBean() {
// instantiate, configure and return bean ...
}
}

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) {

// @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

//或
// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
// ctx.register(AppConfig.class);
// ctx.refresh();
// MyBean myBean = ctx.getBean(MyBean.class);

// 如果加载spring-context.xml文件:
// ApplicationContext context = new
// ClassPathXmlApplicationContext("spring-context.xml");
}
}

参考:

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 {
// various @Bean definitions ...
}

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() {
// instantiate, configure and return DataSource
}
}

@Configuration
@Import(DatabaseConfig.class)
public class AppConfig {

private final DatabaseConfig dataConfig;

public AppConfig(DatabaseConfig dataConfig) {
this.dataConfig = dataConfig;
}

@Bean
public MyBean myBean() {
// reference the dataSource() bean method
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; // from XML

@Bean
public MyBean myBean() {
// inject the XML-defined dataSource bean
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() {
// assertions against myBean ...
}
}

参考资料

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html

https://www.cnblogs.com/duanxz/p/7493276.html