序言
Spring @Configuration是一个类级别的注解,用于声明一个Java类为Spring容器所管理的配置类,并在类中声明和定义一个或多个Bean方法。与此同时,@Configuration还可以与其他类级别的注解搭配使用,例如:
- @PropertySource: 将属性配置源添加到Spring的应用环境中
- @Profile:根据不同条件启用特定的配置类
- @EnableScheduling: 启用Spring的定时任务
- @ImportResource: 导入一个或多个配置Bean的资源文件
- @Import: 导入一个或多个配置类
- @ComponentScan: 配置组件扫描指令
- @EnableWebMvc: 提供SPring MVC配置
- @EnableWebSecurity: 提供Spring Security配置
本节内容
- 使用@Configuration注解
- @Configuration和@Autowired
- @Configuration和@PropertySource
- @Configuration和@Profile
- @Configuration和@EnableScheduling
- @Configuration和@ImportResource
- @Configuration和@Import
- @Configuration和@ComponentScan
1.使用@Configuration注解
与往常一样,创建一个AppConfig类,使用@Configuration进行注解,并在类内部使用@Bean注解一个bean方法。
AppConfig.java
<code>@Configuration
public class AppConfig {
@Bean("user")
public UserBean userBean(){
return new UserBean("树下魅狐");
}
}/<code>
接下来,创建一个名为UserBean的Java类,并在main()方法中通过AnnotationConfigApplicationContext获取userBean。
UserBean.java
<code>public class UserBean {
private String username;
public UserBean(String username){
this.username = username;
System.out.println("Initializing UserBean and username is :"+this.username);
}
public String getUsername(){
return this.username;
}
}/<code>
ConfigurationAnnotationApplication.java
<code>@SpringBootApplication
public class ConfigurationAnnotationApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigurationAnnotationApplication.class, args);
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
UserBean user = (UserBean) context.getBean("user");
System.out.println("user`s username = "+user.getUsername());
}
}/<code>
Output
<code>Initializing UserBean and username is :树下魅狐
user`s username = 树下魅狐/<code>
2. @Configuration和@Autowired
在@Configuration注解的类中,可以使用@Autowired注解将外部化的值或者其他的Bean注入其中。例如,我们可以使用@Autowired将Spring的Environment注入到配置类中。
AppConfig.java
<code>@Configuration
public class AppConfig {
@Autowired
private Environment environment;
@Bean("user")
public UserBean userBean(){
System.out.println(environment.getProperty("java.home"));
return new UserBean("树下魅狐");
}
}/<code>
在代码中,通过environment获得java的home路径。
Output
<code>C:\\Program Files\\Java\\jdk1.8.0_221\\jre
Initializing UserBean and username is :树下魅狐
user`s username = 树下魅狐/<code>
3. @Configuration和@PropertySource
@PropertySource注解为我们提供了一种便捷的方式将外部的配置文件属性值配置到Spring的环境中。我们可以在@Configuration注解的类上使用@PropertySource读取配置文件,并在类中使用@Value获得配置文件中属性值。首先,在类路径下创建一个名为app.properties的配置文件内容如下:
app.properties
<code>[email protected]
author.site=https://www.ramostear.com/<code>
接下来,修改AppConfig.java文件,使用@PropertySource加载application.properties文件,并在类中使用@Value读取配置项的值。
AppConfig.java
<code>@Configuration
@PropertySource(value = "classpath:app.properties")
public class AppConfig {
@Value("${author.email}")
private String email;
@Value("${author.site}")
private String site;
@Autowired
private Environment environment;
@Bean("user")
public UserBean userBean(){
System.out.println(environment.getProperty("java.home"));
System.out.println("Author email:"+email);
System.out.println("Author site:"+site);
return new UserBean("树下魅狐");
}
}/<code>
再次运行main()方法,观察控制台输出。
Output
<code>C:\\Program Files\\Java\\jdk1.8.0_221\\jre
Author email:[email protected]
Author site:https://www.ramostear.com
Initializing UserBean and username is :树下魅狐
user`s username = 树下魅狐/<code>
4 @Configuration和@Profile
@Profile是一个很有用的注解,它允许我们根据Spring ActiveProfile的值注册不同的配置文件。例如,在软件开发过程中,我们可以根据项目进展情况,为项目定义不同的配置,如开发用的配置,测试用的配置以及生产环境用的配置等等。在此例子中,我们通过@Profile新增两个配置类DevAppConfig.java和TestAppConfig.java,并在AppConfig.java类上加入@Profile注解。
DevAppConfig.java
<code>@Profile("dev")
@Configuration
public class DevAppConfig {
@Bean
public UserBean userBean(){
return new UserBean("谭朝红");
}
}/<code>
TestAppConfig.java
<code>@Profile("test")
@Configuration
public class TestAppConfig {
@Bean
public UserBean userBean(){
return new UserBean("ramostear");
}
}/<code>
AppConfig.java
<code>@Profile("prod")
@Configuration
@PropertySource(value = "classpath:app.properties")
public class AppConfig {
//...
}/<code>
接下来,修改main()中的代码,并启用dev的配置。
main()
<code>public static void main(String[] args) {
SpringApplication.run(ConfigurationAnnotationApplication.class, args);
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(); //不指定配置类
context.getEnvironment().setActiveProfiles("dev"); //通过profile切换
context.scan("com.ramostear.configuration.annotation");
context.refresh();
UserBean user = context.getBean(UserBean.class);
System.out.println(user.getUsername());
context.close();
}/<code>
Output
<code>Initializing UserBean and username is :谭朝红
谭朝红/<code>
现在,将profile切换到test,观察控制台输出。
main()
<code>context.getEnvironment().setActiveProfiles("test");/<code>
Output
<code>Initializing UserBean and username is :ramostear
ramostear/<code>
最后,将profile切回到prod。
main()
<code>context.getEnvironment().setActiveProfiles("prod");/<code>
Output
<code>C:\\Program Files\\Java\\jdk1.8.0_221\\jre
Author email:[email protected]
Author site:https://www.ramostear.com
Initializing UserBean and username is :树下魅狐
树下魅狐/<code>
补充
除了上述的方法外,还可以使用System.setProperty()方法设置profile。代码如下:
System.setProperty("spring.profiles.active","prod");
5. @Configuration和@EnableScheduling
在Spring中,@Configuration和@EnableScheduling注解搭配,可以开启Spring的定时任务功能,并使用@Scheduled注解定义定时任务。请看下面的例子:
DemoTask.java
<code>public class DemoTask {
private int num = 0;
private static SimpleDateFormat sdf =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Scheduled(fixedRate = 1000)
public void task(){
System.out.println(sdf.format(new Date())+": number = "+(++num));
}
}/<code>
DemoTask.java任务比较简单,每个一秒输出当前时间和num累加的结果。接下来,在AppConfig.java中开启定时任务,并配置DemoTask bean。
AppConfig.java
<code>@Profile("prod")
@Configuration
@PropertySource(value = "classpath:app.properties")
@EnableScheduling
public class AppConfig {
//省略其他...
@Bean
public DemoTask demoTask(){
return new DemoTask();
}
}/<code>
Output
<code>2020-03-27 06:12:53.048 INFO 7652 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler'
2020-03-27 06:12:53: number = 1
2020-03-27 06:12:54: number = 2
2020-03-27 06:12:55: number = 3
2020-03-27 06:12:56: number = 4
2020-03-27 06:12:57: number = 5
2020-03-27 06:12:58: number = 6
2020-03-27 06:12:59: number = 7
2020-03-27 06:13:00: number = 8
2020-03-27 06:13:01: number = 9
2020-03-27 06:13:02: number = 10/<code>
6.@Configuration 和 @ImportResource
Spring允许我们使用@ImportResource注解导入Spring的XML配置文件。Spring现在推荐使用Java代码的配置方式,但还是给喜好使用XML配置文件的开发者提供了通道。请看示例:
app.xml
<code>
<beans> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean>
<constructor-arg>
/<bean>
/<beans>/<code>
接下来,在AppConfig.java文件中使用@ImportResource注解导入app.xml配置。
AppConfig.java
<code>@Profile("prod")
@Configuration
@PropertySource(value = "classpath:app.properties")
@EnableScheduling
@ImportResource(value = "classpath:app.xml")
public class AppConfig {
//省略...
}/<code>
在main()方法中获取unaBoot 并打印username的值。
main()
<code>public static void main(String[] args) {
SpringApplication.run(ConfigurationAnnotationApplication.class, args);
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("prod");
context.scan("com.ramostear.configuration.annotation");
context.refresh();
UserBean unaBoot = (UserBean) context.getBean("unaBoot");
System.out.println("app.xml config bean :"+ unaBoot.getUsername());
}/<code>
Output
<code>Initializing UserBean and username is :unaBoot
unaBoot
app.xml config bean :unaBoot/<code>
7. @Configuration 和 @Import
我们可以使用@Import将一个或多个被@Configuration注解的配置类导入了一个类当中。这是个不错的操作,可以将多个配置类聚合到一个类中。请看示例:
OtherAppConfig.java
<code>@Configuration
public class OtherAppConfig {
@Bean
public OtherBean otherBean(){
return new OtherBean();
}
}/<code>
在AppConfig.java文件导入OtherAppConfig配置,main()方法中的代码保持不变,内容如下:
<code>@Profile("prod")
@Configuration
@PropertySource(value = "classpath:app.properties")
@EnableScheduling
@ImportResource(value = "classpath:app.xml")
@Import(OtherAppConfig.class)
public class AppConfig {
//省略其他...
}/<code>
OtherBean.java
<code>public class OtherBean {
public OtherBean(){
System.out.println("Initializing other bean ....");
}
}/<code>
Output
<code>Initializing other bean ..../<code>
8. @Configuration 和@ComponentScan
@ComponentScan注解的作用是根据指定的包路径或者类,对组件进行扫描并完成自动装配工作。在前面的章节中已有介绍,在此不再赘述。
本章节通过七个详细的案例,介绍了Spring @Configuration注解的使用,如需文中完整的案例代码,你可以点击下面的地址访问github仓库进行下载。
閱讀更多 ramostear 的文章