(每日一文快速入門)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




分享到:


相關文章: