網頁

2019/4/28

Spring @Configuration作用

以下簡單介紹Spring的@Configuration的作用。


@Configuration的作用同以前的xml配置檔(例如Spring的applicationContext.xmldispatcher-servlet.xml),用來設定Spring環境配置,例如宣告及註冊bean至Spring容器中,注入properties參數等。

例如我們有一個FooService類別,若此類別要成為Spring容器管理的bean,除了一般在該類別上宣告@Component並搭配@ComponentScan掃描的方式註冊為bean,也可透過在@Configuration類別中搭配@Bean的方式註冊。

例如建立一個AppConfig並在類別名稱前掛上@Configuration,則此類別及成為Spring的配置類別。

在配置類的方法前掛上@Bean則方法回傳的物件就會被註冊為Spring容器管理的bean,例如下面的fooService()方法便會將FooService註冊為bean。

package idv.matt.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import idv.matt.demo.service.FooService;

@Configuration
public class AppConfig {

    @Bean
    public FooService fooService() {
        return new FooService();
    }

}

而在Spring Boot中,@SpringBootApplication類本身即包含了@Configuration,所以可以直接在裡面進行如上的配置,例如

package idv.matt.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import idv.matt.demo.service.FooService;

@SpringBootApplication
public class SpringBootBeanDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootBeanDemoApplication.class, args);
    }

    @Bean
    public FooService fooService() {
        return new FooService();
    }

}

為了程式管理及維護上的方便,通常我們會把某些相關的配置寫在另外的配置檔,而不是全部塞在同一個類別,此時就可以利用@Configuration另外定義一個配置檔,例如上面的AppConfig

Spring Boot的@SpringBootApplication預設只會掃描所屬package下的類,因此若@Configuration類別定義在@SpringBootApplication類以外的package,則要用scanBasePackages屬性來設定要額外掃描的package,例如@SpringBootApplication(scanBasePackages="idv.matt.config")

@Configuration包含了@Component),
package idv.matt.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages="idv.matt.config") // 注意package名稱
public class SpringBootBeanDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootBeanDemoApplication.class, args);
    }

}
或是透過@Import來引入,例如
package idv.matt.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Import(value = { idv.matt.config.AnotherAppConfig.class }) // 注意pacakge名稱
public class SpringBootBeanDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootBeanDemoApplication.class, args);
    }

}

那為什麼不直接用以前xml的方式來設定就好呢,因為Spring Boot建議以Java-based的方式來配置,好處是如果在Java程式中設定時若型別不符或不存在,compiler會告知你錯誤,但xml的並不會,直到你啟動專案後才跳錯。此外xml比Java的設定方式肥上許多。另外IDE工具可以幫你在Java程式間迅速找到某個類別或方法,但xml常常找個對應的bean類別要找老半天。


參考:

沒有留言:

張貼留言