SpringBoot 約定大於配置 的功力讓我們如沐春風。用過Spring Boot的應該都知道,在項目啓動入口的主類main()方法裏,一句簡簡單單的便開啓了項目的啓動運行之路。
@SpringBootApplication
public class SpringApplication {
public static void main(String[] args) {
SpringApplication.run(SpringApplication.class, args);
}
}
一、@SpringBootApplication註解
@SpringBootApplication 註解實際上是SpringBoot提供的一個複合註解,下面是2.3.3.RELEASE版本的源碼。
@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 {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
@AliasFor(
annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "nameGenerator"
)
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
我們可以看到主要有三個核心註解。
- @SpringBootConfiguration:該註解的源碼裏面就是@Configuration註解,標註該類爲配置類,並且把該類注入到Baen容器裏面。
- @EnableAutoConfiguration:該註解啓用自動配置,把所有JavaConfig @Configuration 配置都加載到當前Bean容器裏面。作爲核心註解,會單獨講解。
- @ComponentScan:該註解用於掃包,如:@Controller、@Entity、@Component、@Service等註解進行掃描。還可以通過 basePackages 屬性來更細粒度的控制該註解的自動掃描範圍,比如:@ComponentScan(basePackages = {"cn.codesheep.controller","cn.codesheep.entity"})
@EnableAutoConfiguration
源碼爲:
@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 藉助 AutoConfigurationImportSelector 的幫助,而後者通過實現 selectImports() 方法來導出 Configuration。
這裏isEnable()方法判斷了是否開啓自動配置,如果開啓成功,則getProperty()。getProperty()本類中沒有,那就是在他的父類中點擊AutoConfigurationImportSelector找到selectImports()方法,這個方法的作用就是查詢propertis文件加載全類名。我們繼續看this.getCandidateConfigurations(annotationMetadata, attributes)這個方法。
我們看到調用了SpringFactoriesLoader這個類。
SpringFactoriesLoader.loadFactoryNames() 讀取了 ClassPath 下面的 META-INF/spring.factories 文件來獲取所有導出類。
我們在spring.factories文件中,發現了SpringBoot加載了很多開源技術,如rsocket、mongo、elasticsearch等。通過這個來完成自動裝配的功能。