springboot自動配置的核心思想是:springboot通過spring.factories能把main方法所在類路徑以外的bean自動加載
springboot starter驗證
我在springboot啟動方法所轄的包外添加三個類:
1 @Configuration//開啟配置 2 @EnableConfigurationProperties(HelloProperties.class)//開啟使用映射實體對象 3 @ConditionalOnClass(TestHello.class)//存在HelloService時初始化該配置類 4 @ConditionalOnProperty//存在對應配置信息時初始化該配置類 5 ( 6 prefix = "zxp.hello",//存在配置前綴hello 7 value = "flag"//開啟 8 ) 9 public class HelloAutoConfiguration { 10 @Autowired 11 private HelloProperties helloProperties; 12 13 @Bean//創建HelloService實體bean 14 @ConditionalOnMissingBean(TestHello.class)//缺失HelloService實體bean時,初始化HelloService並添加到SpringIoc 15 public TestHello helloService() 16 { 17 System.out.println(">>>The TestHello Not Found,Execute Create New Bean."); 18 TestHello testHello = new TestHello(helloProperties.getName(),helloProperties.getFlag()); 19 return testHello; 20 } 21 }
@ConfigurationProperties(prefix = "zxp.hello") @Data public class HelloProperties { private String name; private String flag; }
public class TestHello { String name; String flag; public TestHello(String name, String flag) { this.name = name; this.flag = flag; } public String print(){ String msg = "name is "+name + " " + "flag is "+flag; System.out.println(msg); return msg; } }
在main方法所在包范圍內新建Controller
@RestController public class TempController { @Autowired TestHello testHello;//無法注入,報錯!!!! @RequestMapping("/test/boot") public String boot(){ return testHello.print(); } }
會在上面代碼標注位置報錯。因為 TestHello並沒有托管給spring管理。
在resources下創建META-INF路徑,並創建spring.factories文件
#配置自定義Starter的自動化配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=springbootautoconfig.test.config.HelloAutoConfiguration
再試啟動又報錯了
- Bean method 'helloService' not loaded because @ConditionalOnProperty (zxp.hello) did not find property 'flag'
原因是如果沒有配置zxp.hello.flag會報錯
@ConditionalOnProperty//存在對應配置信息時初始化該配置類 ( prefix = "zxp.hello",//存在配置前綴hello value = "flag"//開啟 )
這里如果不想報錯,需要加入 matchIfMissing = false
在application.properties中添加
zxp.hello.flag=2
成功了,訪問controller,返回“name is null flag is 1”
SpringBoot starter部分注解說明
@ConditionalOnXxx 可以根據條件來決定是否執行自動配置
@ConditionalOnBean:當SpringIoc容器內存在指定Bean的條件
@ConditionalOnClass:當SpringIoc容器內存在指定Class的條件
@ConditionalOnExpression:基於SpEL表達式作為判斷條件
@ConditionalOnJava:基於JVM版本作為判斷條件
@ConditionalOnJndi:在JNDI存在時查找指定的位置
@ConditionalOnMissingBean:當SpringIoc容器內不存在指定Bean的條件
@ConditionalOnMissingClass:當SpringIoc容器內不存在指定Class的條件
@ConditionalOnNotWebApplication:當前項目不是Web項目的條件
@ConditionalOnProperty:指定的屬性是否有指定的值
@ConditionalOnResource:類路徑是否有指定的值
@ConditionalOnSingleCandidate:當指定Bean在SpringIoc容器內只有一個,或者雖然有多個但是指定首選的Bean
@ConditionalOnWebApplication:當前項目是Web項目的條件
SpringBoot starter原理
@SpringBootApplication -》 @EnableAutoConfiguration -》@Import(AutoConfigurationImportSelector.class)
SpringFactoriesLoader.loadFactoryNames方法掃描了所有JAR包的META-INF/spring.factories
spring-boot-autoconfigure包內的spring.factories文件內容
work.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
……非常多,包含了JPA的,包含了spring官方推薦starter的aotuconfig