我們在開發springBoot的時候需要明白springBoot的流程是什麼樣的。
一:SpringBoot重要註解說明
我們在進行springBoot相關開發的時候,通常需要引入springBoot相關的註解,首先在啓動類中添加@SpringBootApplication
@SpringBootApplication
public class TestApplication {
public static void main(String[] args){
SpringApplication.run(TestApplication.class,args);
}
}
我們深入看下SpringBootApplication裏有什麼??
package org.springframework.boot.autoconfigure;
@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) })
public @interface SpringBootApplication {
......
}
在看下SpringBootConfiguration有啥。
package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
所以可以看出@SpringBootApplication中主要是如下三個重要的註解。
@EnableAutoConfiguration
:啓用 SpringBoot 的自動配置機制@ComponentScan
: 掃描被@Component
(@Service
,@Controller
)註解的bean,註解默認會掃描該類所在的包下所有的類。@Configuration
:允許在上下文中註冊額外的bean或導入其他配置類
二:@EnableAutonCinfiguration的自動配置是如何實現的。
上面我們看到EnableAutoConfiguration是springBoot的自動配置,那他是如何實現的呢。我們看下源碼
@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 {};
}
@EnableAutoConfiguration
註解通過Spring 提供的 @Import
註解導入了AutoConfigurationImportSelector
類(@Import
註解可以導入配置類或者Bean到當前類中)。
AutoConfigurationImportSelector
類中getCandidateConfigurations
方法會將所有自動配置類的信息以 List 的形式返回。這些配置信息會被 Spring 容器作 bean 來管理。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
自動配置信息有了,那麼自動配置還差什麼呢?
@Conditional
註解。@ConditionalOnClass
(指定的類必須存在於類路徑下),@ConditionalOnBean
(容器中是否有指定的Bean)等等都是對@Conditional
註解的擴展。拿 Spring Security 的自動配置舉個例子:
SecurityAutoConfiguration
中導入了WebSecurityEnablerConfiguration
類,WebSecurityEnablerConfiguration
源代碼如下:
@Configuration
@ConditionalOnBean(WebSecurityConfigurerAdapter.class)
@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@EnableWebSecurity
public class WebSecurityEnablerConfiguration {
}
WebSecurityEnablerConfiguration
類中使用@ConditionalOnBean
指定了容器中必須還有WebSecurityConfigurerAdapter
類或其實現類。所以,一般情況下 Spring Security 配置類都會去實現 WebSecurityConfigurerAdapter
,這樣自動將配置就完成了。