(每日一文快速入门)Spring @Configuration Annotation


(每日一文快速入门)Spring @Configuration Annotation


序言

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仓库进行下载。


(每日一文快速入门)Spring @Configuration Annotation

https://github.com/ramostear/spring-annotations-daily-example




分享到:


相關文章: