Spring @Configuration注解

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

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

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

一、用`@Configuration加载spring
1.1、@Configuration配置spring并启动spring容器
1.2、@Configuration启动容器+@Bean注册Bean
1.3、@Configuration启动容器+@Component注册Bean
1.4、使用 AnnotationConfigApplicationContext 注册 AppContext 类的两种方法
1.5、配置Web应用程序(web.xml中配置
AnnotationConfigApplicationContext)
1.6、@Configuation总结
二、组合多个配置类
2.1、在@configuration中引入spring的xml配置文件
2.2、在@configuration中引入其它注解配置
2.3、@configuration嵌套(嵌套的Configuration必须是静态类)
三、@EnableXXX注解
四、@Profile逻辑组配置
五、使用外部变量

一、@Configuation加载Spring方法

1.1、@Configuration配置spring并启动spring容器

@Configuration标注在类上,相当于把该类作为spring的xml配置文件中的,作用为:配置spring容器(应用上下文)

1package config;
2import org.springframework.context.annotation.Configuration;
3@Configuration
4public class TestConfiguration {
5
6 public TestConfiguration(){
7 System.out.println(“TestConfiguration 容器启动初始化…”);
8 }
9}
相当于

1
2 3 xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
4 xmlns:context=“http://www.springframework.org/schema/context”
5 xsi:schemaLocation=“http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans.xsd
7 http://www.springframework.org/schema/context
8 http://www.springframework.org/schema/context/spring-context.xsd”>
9
10
主方法进行测试:

1package config;
2
3import org.springframework.context.ApplicationContext;
4import org.springframework.context.annotation.AnnotationConfigApplicationContext;
5
6public class TestConfig {
7 public static void main(String[] args){
8 // @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
9 ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
10
11 // 如果加载spring-context.xml文件:
12 // ApplicationContext context = new
13 // ClassPathXmlApplicationContext(“spring-context.xml”);
14 }
15}
测试结果如下:

1四月 03, 2018 10:12:52 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
2信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@179d3b25: startup date [Tue Apr 03 10:12:52 CST 2018]; root of context hierarchy
3TestConfiguration 容器启动初始化…
从运行主方法结果可以看出,spring容器已经启动了:

1.2、@Configuration启动容器+@Bean注册Bean,@Bean下管理bean的生命周期

@Bean标注在方法上(返回某个实例的方法),等价于spring的xml配置文件中的,作用为:注册bean对象

bean类:

1package model;
2
3public class User {
4 private String userName;
5 private String password;
6 private String url;
7
8 public void sayHello(){
9 System.out.println(“User sayHello…”);
10 }
11
12 public void start(){
13 System.out.println(“User 初始化…”);
14 }
15
16 public void cleanUp(){
17 System.out.println(“User 销毁…”);
18 }
19}
配置类

1package config;
2
3import model.User;
4import org.springframework.context.annotation.Bean;
5import org.springframework.context.annotation.Configuration;
6import org.springframework.context.annotation.Scope;
7
8@Configuration
9public class TestConfiguration {
10
11 public TestConfiguration(){
12 System.out.println(“TestConfiguration 容器启动初始化…”);
13 }
14
15 @Bean
16 @Scope(“prototype”)
17 public User user(){
18 return new User();
19 }
20}
主方法测试类:

1package config;
2
3import model.User;
4import org.springframework.context.ApplicationContext;
5import org.springframework.context.annotation.AnnotationConfigApplicationContext;
6
7public class TestConfig {
8 public static void main(String[] args){
9 // @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
10 ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
11
12 // 如果加载spring-context.xml文件:
13 // ApplicationContext context = new
14 // ClassPathXmlApplicationContext(“spring-context.xml”);
15
16 //获取bean
17 User user = (User)context.getBean(“user”);
18 user.sayHello();
19 }
20}
测试结果:

1四月 03, 2018 10:46:10 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
2信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@179d3b25: startup date [Tue Apr 03 10:46:10 CST 2018]; root of context hierarchy
3TestConfiguration 容器启动初始化…
4User sayHello…
注:
(1)、@Bean注解在返回实例的方法上,如果未通过@Bean指定bean的名称,则默认与标注的方法名相同;
(2)、@Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为原型作用域;
(3)、既然@Bean的作用是注册bean对象,那么完全可以使用@Component、@Controller、@Service、@Repository等注解注册bean,当然需要配置@ComponentScan注解进行自动扫描。

@Bean下管理bean的生命周期

可以使用基于 Java 的配置来管理 bean 的生命周期。@Bean 支持两种属性,即 initMethod 和destroyMethod,这些属性可用于定义生命周期方法。在实例化 bean 或即将销毁它时,容器便可调用生命周期方法。生命周期方法也称为回调方法,因为它将由容器调用。使用 @Bean 注释注册的 bean 也支持 JSR-250 规定的标准 @PostConstruct 和 @PreDestroy 注释。如果您正在使用 XML 方法来定义 bean,那么就应该使用 bean 元素来定义生命周期回调方法。以下代码显示了在 XML 配置中通常使用 bean 元素定义回调的方法。

1package config;
2
3import model.User;
4import org.springframework.context.annotation.Bean;
5import org.springframework.context.annotation.Configuration;
6import org.springframework.context.annotation.Scope;
7
8@Configuration
9public class TestConfiguration {
10
11 public TestConfiguration(){
12 System.out.println(“TestConfiguration 容器启动初始化…”);
13 }
14
15 //@Bean注解注册bean,同时可以指定初始化和销毁方法
16 @Bean(name=“testBean”,initMethod=“start”,destroyMethod=“cleanUp”)
17 @Scope(“prototype”)
18 public User user(){
19 return new User();
20 }
21}
启动类:

1package config;
2
3import model.User;
4import org.springframework.context.ApplicationContext;
5import org.springframework.context.annotation.AnnotationConfigApplicationContext;
6
7public class TestConfig2 {
8 public static void main(String[] args) {
9 ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
10
11 User userA = (User)context.getBean(“user”);
12 userA.sayHello();
13 System.out.println(userA);
14
15 User userB = (User)context.getBean(“user”);
16 userB.sayHello();
17 System.out.println(userB);
18 }
19}
结果:

1四月 03, 2018 10:58:33 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
2信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@179d3b25: startup date [Tue Apr 03 10:58:33 CST 2018]; root of context hierarchy
3TestConfiguration 容器启动初始化…
4User 初始化…
5User sayHello…
6model.User@5579bb86
7User 初始化…
8User sayHello…
9model.User@5204062d
分析:

通过打印 “User 初始化…”,表面 initMethod 生效。
通过打印的“model.User@5579bb86”和“model.User@5579bb86”,表明@Scope(“prototype”)生效
1.3、@Configuration启动容器+@Component注册Bean

bean类:

1package model;
2
3import org.springframework.stereotype.Component;
4
5//添加注册bean的注解
6@Component
7public class User {
8 private String userName;
9 private String password;
10 private String url;
11
12 public void sayHello(){
13 System.out.println(“User sayHello…”);
14 }
15
16 public void start(){
17 System.out.println(“User 初始化…”);
18 }
19
20 public void cleanUp(){
21 System.out.println(“User 销毁…”);
22 }
23}
配置类:

1package config;
2
3import model.User;
4import org.springframework.context.annotation.Bean;
5import org.springframework.context.annotation.ComponentScan;
6import org.springframework.context.annotation.Configuration;
7import org.springframework.context.annotation.Scope;
8
9@Configuration
10//添加自动扫描注解,basePackages为User包路径
11@ComponentScan(basePackages = “model”)
12public class TestConfiguration {
13
14 public TestConfiguration(){
15 System.out.println(“TestConfiguration 容器启动初始化…”);
16 }
17
18 ///@Bean注解注册bean,同时可以指定初始化和销毁方法
19 @Bean(name=“user”,initMethod=“start”,destroyMethod=“cleanUp”)
20 @Scope(“prototype”)
21 public User user(){
22 return new User();
23 }
/
24}
主方法测试获取bean对象:

1package config;
2
3import model.User;
4import org.springframework.context.ApplicationContext;
5import org.springframework.context.annotation.AnnotationConfigApplicationContext;
6
7public class TestConfig {
8 public static void main(String[] args){
9 // @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
10 ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
11
12 // 如果加载spring-context.xml文件:
13 // ApplicationContext context = new
14 // ClassPathXmlApplicationContext(“spring-context.xml”);
15
16 //获取bean
17 User user = (User)context.getBean(“user”);
18 user.sayHello();
19 }
20}
测试结果:

1四月 03, 2018 11:07:54 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
2信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@179d3b25: startup date [Tue Apr 03 11:07:54 CST 2018]; root of context hierarchy
3TestConfiguration 容器启动初始化…
4User sayHello…
sayHello() 方法被正常调用

1.4、使用 AnnotationConfigApplicationContext 注册 AppContext 类的两种方法

1.4.1、 配置类的注册方式是将其传递给 AnnotationConfigApplicationContext 构造函数

1public static void main(String[] args){
2 // @Configuration注解的spring容器加载方式,用AnnotationConfigApplicationContext替换ClassPathXmlApplicationContext
3 ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
4 //获取bean
5 User user = (User)context.getBean(“user”);
6 user.sayHello();
7}
1.4.2、 AnnotationConfigApplicationContext 的register 方法传入配置类来注册配置类

1public static void main(String[] args){
2 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
3 context.register(TestConfiguration.class);
4 context.refresh();
5 //获取bean
6 User user = (User)context.getBean(“user”);
7 user.sayHello();
8}
1.5、配置Web应用程序(web.xml中配置AnnotationConfigApplicationContext)

过去,您通常要利用 XmlWebApplicationContext 上下文来配置 Spring Web 应用程序,即在 Web 部署描述符文件 web.xml 中指定外部 XML 上下文文件的路径。XMLWebApplicationContext 是 Web 应用程序使用的默认上下文类。以下代码描述了 web.xml 中指向将由 ContextLoaderListener 监听器类载入的外部 XML 上下文文件的元素。

1
2
3 contextConfigLocation
4 /WEB-INF/applicationContext.xml
5
6
7
8 org.springframework.web.context.ContextLoaderListener
9
10
11
12 sampleServlet
13
14 org.springframework.web.servlet.DispatcherServlet
15
16
17
18…
19
现在,您要将 web.xml 中的上述代码更改为使用 AnnotationConfigApplicationContext 类。切记,XmlWebApplicationContext 是 Spring 为 Web 应用程序使用的默认上下文实现,因此您永远不必在您的web.xml 文件中显式指定这个上下文类。现在,您将使用基于 Java 的配置,因此在配置 Web 应用程序时,需要在web.xml 文件中指定 AnnotationConfigApplicationContext 类。上述代码将修改如下:

1
2
3 contextClass
4
5 org.springframework.web.context.
6 support.AnnotationConfigWebApplicationContext
7
8
9
10 contextConfigLocation
11
12 demo.AppContext
13
14
15
16
17 org.springframework.web.context.ContextLoaderListener
18
19
20
21 sampleServlet
22
23 org.springframework.web.servlet.DispatcherServlet
24
25
26 contextClass
27
28 org.springframework.web.context.
29 support.AnnotationConfigWebApplicationContext
30
31
32
33
34…
35
以上修改后的 web.xml 现在定义了 AnnotationConfigWebApplicationContext 上下文类,并将其作为上下文参数和 servlet 元素的一部分。上下文配置位置现在指向 AppContext 配置类。这非常简单。下一节将演示 bean 的生命周期回调和范围的实现。

1.6、@Configuation总结

@Configuation等价于
@Bean等价于
@ComponentScan等价于
二、组合多个配置类

2.1、在@configuration中引入spring的xml配置文件

bean类:

1package model;
2public class Person {
3 private String userName;
4 private String password;
5 private String url;
6 public void sayHello(){
7 System.out.println(“Person sayHello…”);
8 }
9 public void start(){
10 System.out.println(“Person 初始化…”);
11 }
12 public void cleanUp(){
13 System.out.println(“Person 销毁…”);
14 }
15}
applicationContext.xml文件:

1
2 3 xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
4 xsi:schemaLocation=“http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd”>
5
6
7
配置类:

1package config;
2import org.springframework.context.annotation.ComponentScan;
3import org.springframework.context.annotation.Configuration;
4import org.springframework.context.annotation.ImportResource;
5@Configuration
6@ImportResource(“classpath:applicationContext.xml”)
7public class TestConfiguration2 {
8 public TestConfiguration2(){
9 System.out.println(“TestConfiguration2 容器启动初始化…”);
10 }
11}
测试类:

1package config;
2
3import model.Person;
4import model.User;
5import org.springframework.context.ApplicationContext;
6import org.springframework.context.annotation.AnnotationConfigApplicationContext;
7
8public class TestConfig3 {
9 public static void main(String[] args) {
10 ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration2.class);
11
12 Person person = (Person)context.getBean(“person”);
13 person.sayHello();
14 }
15}
测试结果

1四月 03, 2018 11:30:35 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
2信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@179d3b25: startup date [Tue Apr 03 11:30:35 CST 2018]; root of context hierarchy
3四月 03, 2018 11:30:35 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
4信息: Loading XML bean definitions from class path resource [applicationContext.xml]
5TestConfiguration2 容器启动初始化…
6Person sayHello…
2.2、在@configuration中引入其它注解配置

1package config;
2
3import org.springframework.context.annotation.ComponentScan;
4import org.springframework.context.annotation.Configuration;
5import org.springframework.context.annotation.Import;
6import org.springframework.context.annotation.ImportResource;
7
8@Configuration
9@ImportResource(“classpath:applicationContext.xml”)
10@Import(TestConfiguration.class)
11public class TestConfiguration2 {
12
13 public TestConfiguration2(){
14 System.out.println(“TestConfiguration2 容器启动初始化…”);
15 }
16
17}
测试类:

1package config;
2
3import model.Person;
4import model.User;
5import org.springframework.context.ApplicationContext;
6import org.springframework.context.annotation.AnnotationConfigApplicationContext;
7
8public class TestConfig3 {
9 public static void main(String[] args) {
10 ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration2.class);
11
12 Person person = (Person)context.getBean(“person”);
13 person.sayHello();
14
15 User user = (User)context.getBean(“user”);
16 user.sayHello();
17 }
18}
测试结果:

1四月 03, 2018 11:55:10 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
2信息: Loading XML bean definitions from class path resource [applicationContext.xml]
3TestConfiguration2 容器启动初始化…
4TestConfiguration 容器启动初始化…
5Person sayHello…
6User sayHello…
2.3、@configuration嵌套(嵌套的Configuration必须是静态类)

通过配置类嵌套的配置类,达到组合多个配置类的目的。但注意内部类必须是静态类。

上代码:

1package model;
2
3public class DataSource {
4 private String dbUser;
5 private String dbPass;
6 public String getDbUser() {
7 return dbUser;
8 }
9 public void setDbUser(String dbUser) {
10 this.dbUser = dbUser;
11 }
12 public String getDbPass() {
13 return dbPass;
14 }
15 public void setDbPass(String dbPass) {
16 this.dbPass = dbPass;
17 }
18 @Override
19 public String toString() {
20 return “DataSource [dbUser=” + dbUser + “, dbPass=” + dbPass + “]”;
21 }
22}
23
24
25
26package model;
27
28import org.springframework.stereotype.Component;
29
30//添加注册bean的注解
31@Component
32public class User {
33 private String userName;
34 private String password;
35 private String url;
36
37 public void sayHello(){
38 System.out.println(“User sayHello…”);
39 }
40
41 public void start(){
42 System.out.println(“User 初始化…”);
43 }
44
45 public void cleanUp(){
46 System.out.println(“User 销毁…”);
47 }
48}
配置类

1package config;
2import model.DataSource;
3import org.springframework.context.annotation.*;
4@Configuration
5@ComponentScan(basePackages = “model”)
6public class TestConfiguration3 {
7 public TestConfiguration3(){
8 System.out.println(“TestConfiguration3 容器启动初始化…”);
9 }
10 @Configuration
11 static class DatabaseConfig{
12 @Bean
13 DataSource dataSource(){
14 return new DataSource();
15 }
16 }
17}
测试启动类:

1package config;
2import model.DataSource;
3import model.Person;
4import model.User;
5import org.springframework.context.ApplicationContext;
6import org.springframework.context.annotation.AnnotationConfigApplicationContext;
7public class TestConfig4 {
8 public static void main(String[] args) {
9 ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration3.class);
10 User user = (User)context.getBean(“user”);
11 user.sayHello();
12 DataSource dataSource = (DataSource)context.getBean(“dataSource”);
13 System.out.println(dataSource);
14 }
15}
结果

1四月 03, 2018 12:05:42 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
2信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@179d3b25: startup date [Tue Apr 03 12:05:42 CST 2018]; root of context hierarchy
3TestConfiguration3 容器启动初始化…
4User sayHello…
5DataSource [dbUser=null, dbPass=null]
3、@EnableXXX注解

配合@Configuration使用,包括 @EnableAsync, @EnableScheduling, @EnableTransactionManagement, @EnableAspectJAutoProxy, @EnableWebMvc。

@EnableAspectJAutoProxy—《spring AOP 之:@Aspect注解》

@EnableScheduling–《Spring 3.1新特性之二:@Enable*注解的源码,spring源码分析之定时任务Scheduled注解》

4、@Profile逻辑组配置

见《Spring的@PropertySource + Environment,@PropertySource(PropertySourcesPlaceholderConfigurer)+@Value配合使用》

5、使用外部变量

1、@PropertySource + Environment,通过@PropertySource注解将properties配置文件中的值存储到Spring的 Environment中,Environment接口提供方法去读取配置文件中的值,参数是properties文件中定义的key值。
2、@PropertySource(PropertySourcesPlaceholderConfigurer)+@Value

见《Spring的@PropertySource + Environment,@PropertySource(PropertySourcesPlaceholderConfigurer)+@Value配合使用》

原文地址:https://www.cnblogs.com/duanxz/p/7493276.html

你可能感兴趣的:(Spring)