springboot autoconfig
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