先看下@SpringBootApplication這個註解,這是一個組合註解,部分源碼以下:git
@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 { //省略若干代碼... }
能夠看到@EnableAutoConfiguration這個註解,這個就是自動配置的核心所在,接下來看下這個註解的源碼:github
@SuppressWarnings("deprecation") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { //省略若干行代碼... }
能夠發現此處導入了EnableAutoConfigurationImportSelector.class這個類,繼續觀察EnableAutoConfigurationImportSelector這個類的源碼web
public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector { //省略若干行代碼 }
發現繼承於AutoConfigurationImportSelector這個類,發現有以下代碼spring
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; }
這裏掃描了具備META-INF/spring.factories文件的jar包。點開具備*autoconfigure的包,打開META-INF/spring.factories文件,發現有相似org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration
,打開任意一個AutoConfiguration,能夠發現有以下註解:安全
@Configuration @EnableConfigurationProperties(UeditorProperties.class) @ConditionalOnClass(ActionEnter.class) @ConditionalOnProperty(prefix="ueditor",value="enabled",matchIfMissing=true)
這裏即是spring-boot自動配置的祕密所在了,接下來本身建一個項目,讓其也擁有自動配置的功能:當類存在時,自動配置這個類的Bean,並可將Bean的屬性在appliction.properties中配置。springboot
<dependencies> <!--自動配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>${spring-boot}</version> </dependency> <!--屬性的自動注入--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> <version>${spring-boot}</version> </dependency> </dependencies>
@ConfigurationProperties(prefix = "hello") public class HelloServiceProperties { private static final String MSG = "world"; private String msg = MSG; public static String getMSG() { return MSG; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
public class HelloService { private String msg; public String sayHello(){ return "hello"+msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
@Configuration @EnableConfigurationProperties(HelloServiceProperties.class) @ConditionalOnClass(HelloService.class) public class HelloServiceAutoConfigure { @Autowired private HelloServiceProperties helloServiceProperties; @Bean @ConditionalOnMissingBean(HelloService.class) public HelloService helloService() { HelloService helloService = new HelloService(); helloService.setMsg(helloServiceProperties.getMsg()); return helloService; } }
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.xiake.springboot.start.hello.HelloServiceAutoConfigure
這裏,一個擁有自動配置的項目完成。在其餘項目中引用maven座標,並在application.properties中自定義hello.msg="xxx".使用代碼以下:app
@Autowired HelloService helloService; @ResponseBody @RequestMapping("/sayHello") public ResponseData sayHello(HttpServletRequest request){ return ResponseData.success(helloService.sayHello()); //輸出hello.msg中的內容:xxx }
項目源碼地址maven