沉默的背影 X-Pacific

keep learning

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

 

posted @ 2019-04-13 16:25  乂墨EMO  阅读(2553)  评论(0编辑  收藏  举报