Spring Boot自動化配置
§ Spring Boot的顯著優勢
- 使用starter簡化依賴配置
- Spring的自動配置
§ starter簡化依賴的配置
Spring提供了一系列starter來簡化Maven配置。當我們在我們的pom文件中增加對某個starter的依賴時,該starter的依賴也會自動的傳遞性被依賴進來。
§ 自動配置
Spring Boot會根據==類路徑中的jar包、類,爲jar包裏的類自動配置==,這樣可以極大的減少配置的數量。簡單點說就是它會根據定義在classpath下的類,自動的給你生成一些Bean,並加載到Spring的Context中。
§ 自動配置流程
§ @SpringBootApplication
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) // .....
§ @EnableAutoConfiguration註解
藉助
@Import
的幫助,將所有符合自動配置條件的bean定義加載到IoC容器。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
其中最重要的是第6行:
@Import({AutoConfigurationImportSelector.class})
§ AutoConfigurationImportSelector
該類讀取了ClassPath下面的
META-INF/spring.factories
文件,該文件的配置格式爲“Key=Value”。(搜索一下就可以看到各種依賴的spring.factories文件)***該類讀取
spring.factories
文件中以org.springframework.boot.autoconfigure.EnableAutoConfiguration
爲key的值,這些值都對應着XXXAutoConfiguration
類,然後這些類用來配置生成Bean。***任意選取一個spring.factories文件來看:這裏選了一個hystrix相關的
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\ org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\ org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration
可以看到key
org.springframework.boot.autoconfigure.EnableAutoConfiguration
的值有兩個,分別是HystrixAutoConfiguration
類和HystrixSecurityAutoConfiguration
再選擇
HystrixAutoConfiguration
類進去看一下:@Configuration @ConditionalOnClass({Hystrix.class, HealthIndicator.class, HealthIndicatorAutoConfiguration.class}) @AutoConfigureAfter({HealthIndicatorAutoConfiguration.class}) public class HystrixAutoConfiguration { public HystrixAutoConfiguration() { } @Bean @ConditionalOnEnabledHealthIndicator("hystrix") public HystrixHealthIndicator hystrixHealthIndicator() { return new HystrixHealthIndicator(); } // ....... }
這裏就走了@Configuration和@Bean去進行Bean的配置了。
***還有一點,條件配置,如類中的
@ConditionalOnClass
和@ConditionalOnEnabledHealthIndicator("hystrix")
註解,這些都是用來篩選是否裝配該Bean用的。***
§ 附上流程圖
§ @Configuration和@Component註解區別
@Configuration標註在類上,相當於把該類作爲spring的xml配置文件中的<bean>,作用爲:配置spring容器(應用上下文),內部可以使用@Bean註解定義一些bean,***無需掃描!!!***
Bean類:
public class TestBean { public void sayHello(){ System.out.println("TestBean sayHello..."); } public String toString(){ return "username:"+this.username+",url:"+this.url+",password:"+this.password; } public void start(){ System.out.println("TestBean 初始化。。。"); } public void cleanUp(){ System.out.println("TestBean 銷燬。。。"); } }
配置類:
@Configuration public class TestConfiguration { public TestConfiguration(){ System.out.println("spring容器啓動初始化。。。"); } //@Bean註解註冊bean,同時可以指定初始化和銷燬方法 //@Bean(name="testNean",initMethod="start",destroyMethod="cleanUp") @Bean @Scope("prototype") public TestBean testBean() { // 這裏調用Bean類的構造函數 return new TestBean(); } }
@Component:標註在類上,需在@Configuration所在類加上@ComponentScan,即可自動將其添加爲bean,不用在內部使用@Bean添加。
Bean類:
//添加註冊bean的註解 @Component public class TestBean { public void sayHello(){ System.out.println("TestBean sayHello..."); } public String toString(){ return "username:"+this.username+",url:"+this.url+",password:"+this.password; } }
配置類:
@Configuration //添加自動掃描註解,basePackages爲TestBean包路徑 @ComponentScan(basePackages = "com.test.spring.support.configuration") public class TestConfiguration { // 已經自動將@Component標註的添加爲bean了 public TestConfiguration(){ System.out.println("spring容器啓動初始化。。。"); } }
§ @Bean和@Component
- ***@Bean是作用於方法,方法定義在@Configuration標註的類中,將方法的返回值作爲bean添加到容器中,並且可設置多種參數。***
- @Component作用於類,需要配合@ComponentScan掃描才能添加到容器