SpringBoot Starter原理(依赖引入,自动配置)(十二)

创建SpringBoot应用,我们在使用Web开发时,选择的是spring-boot-starter-web。starter是一种服务,使用某个功能的开发者不需要关注各种依赖库的处理,不需要具体的配置信息,由Spring Boot自动通过classpath路径下的类发现并加载需要的Bean。

原理

SpringBoot Starter原理

利用starter实现自动化配置只需要两个条件——maven依赖、配置文件。引入maven实质上就是导入jar包,spring-boot启动的时候会找到starter jar包中的resources/META-INF/spring.factories文件,根据spring.factories文件中的配置,找到需要自动配置的类。

配置类上面包括以下注解

@Configuration 表明是一个配置文件,被注解的类将成为一个bean配置类

@ConditionalOnClass 当classpath下发现该类的情况下进行自动配置

@ConditionalOnBean 当classpath下发现该类的情况下进行自动配置

@EnableConfigurationProperties 使@ConfigurationProperties注解生效

@AutoConfigureAfter 完成自动配置后实例化这个bean

 

依赖引入

spring-boot-starter 核心Spring Boot starter,包括自动配置支持,日志和YAML

spring-boot-starter-actuator 生产准备的特性,用于帮我们监控和管理应用

spring-boot-starter-amqp 对”高级消息队列协议”的支持,通过spring-rabbit实现

spring-boot-starter-aop 对面向切面编程的支持,包括spring-aop和AspectJ

spring-boot-starter-batch 对Spring Batch的支持,包括HSQLDB数据库

spring-boot-starter-cloud-connectors 对Spring Cloud Connectors的支持,简化在云平台下(例如,Cloud Foundry 和Heroku)服务的连接

spring-boot-starter-data-elasticsearch 对Elasticsearch搜索和分析引擎的支持,包括spring-data-elasticsearch

spring-boot-starter-data-gemfire 对GemFire分布式数据存储的支持,包括spring-data-gemfire

spring-boot-starter-data-jpa 对”Java持久化API”的支持,包括spring-data-jpa,spring-orm和Hibernate

spring-boot-starter-data-mongodb 对MongoDB NOSQL数据库的支持,包括spring-data-mongodb

spring-boot-starter-data-rest 对通过REST暴露Spring Data仓库的支持,通过spring-data-rest-webmvc实现

spring-boot-starter-data-solr 对Apache Solr搜索平台的支持,包括spring-data-solr

spring-boot-starter-freemarker 对FreeMarker模板引擎的支持

spring-boot-starter-groovy-templates 对Groovy模板引擎的支持

spring-boot-starter-hateoas 对基于HATEOAS的RESTful服务的支持,通过spring-hateoas实现

spring-boot-starter-hornetq 对”Java消息服务API”的支持,通过HornetQ实现

spring-boot-starter-integration 对普通spring-integration模块的支持

spring-boot-starter-jdbc 对JDBC数据库的支持

spring-boot-starter-jersey 对Jersey RESTful Web服务框架的支持

spring-boot-starter-jta-atomikos 对JTA分布式事务的支持,通过Atomikos实现

spring-boot-starter-jta-bitronix 对JTA分布式事务的支持,通过Bitronix实现

spring-boot-starter-mail 对javax.mail的支持

spring-boot-starter-mobile 对spring-mobile的支持

spring-boot-starter-mustache 对Mustache模板引擎的支持

spring-boot-starter-redis 对REDIS键值数据存储的支持,包括spring-redis

spring-boot-starter-security 对spring-security的支持

spring-boot-starter-social-facebook 对spring-social-facebook的支持

spring-boot-starter-social-linkedin 对spring-social-linkedin的支持

spring-boot-starter-social-twitter 对spring-social-twitter的支持

spring-boot-starter-test 对常用测试依赖的支持,包括JUnit, Hamcrest和Mockito,还有spring-test模块

spring-boot-starter-thymeleaf 对Thymeleaf模板引擎的支持,包括和Spring的集成

spring-boot-starter-velocity 对Velocity模板引擎的支持

spring-boot-starter-web 对全栈web开发的支持, 包括Tomcat和spring-webmvc

spring-boot-starter-websocket 对WebSocket开发的支持

spring-boot-starter-ws 对Spring Web服务的支持

依赖spring-boot-starter-web,springboot会根据需要自动引入jar包。

 

自动配置

我们引入starter的依赖,会将自动配置的类的jar引入。@SpringBootApplication的注解中有一个是@EnableAutoConfiguration注解,这个注解有一个@Import({EnableAutoConfigurationImportSelector.class}),EnableAutoConfigurationImportSelector内部则是使用了SpringFactoriesLoader.loadFactoryNames方法进行扫描具有META-INF/spring.factories文件的jar包。

启动类上@SpringBootApplication -> 引入AutoConfigurationImportSelector -> ConfigurationClassParser 中处理 -> 获取spring.factories中EnableAutoConfiguration实现

 

1、进入AutoConfigurationImportSelector类的getAutoConfigurationEntry方法

 

 

2、然后进入getCandidateConfigurations类。

该方法作用是获得spring.factories当中实现EnableAutoConfiguration接口的类

 

 

3 获得所有实现了EnableAutoConfiguration的类

 

 

4、最终有WeacherAutoConfiguration

 

 

 

二、自动配置类的过滤

1、进入WeatherAutoConfiguration类

 

 2、进入ConditionalOnProperty注解

 

 

3、然后进入OnPropertyCondition类的getMatchOutcome方法。当metadata为com.exmaple.demo.WeatherAutoConfiguration时

遍历注解里的属性,增加到对应的math或者noMatch集合中。如果存在noMatch,则返回不匹配

 

4、进入determineOutcome方法

private ConditionOutcome determineOutcome(AnnotationAttributes annotationAttributes, PropertyResolver resolver) {

    OnPropertyCondition.Spec spec = new OnPropertyCondition.Spec(annotationAttributes);

    List<String> missingProperties = new ArrayList();

    List<String> nonMatchingProperties = new ArrayList();

    spec.collectProperties(resolver, missingProperties, nonMatchingProperties);

    return !missingProperties.isEmpty()?ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, new Object[]{spec}).didNotFind("property", "properties").items(Style.QUOTE, missingProperties)):(!nonMatchingProperties.isEmpty()?ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnProperty.class, new Object[]{spec}).found("different value in property", "different value in properties").items(Style.QUOTE, nonMatchingProperties)):ConditionOutcome.match(ConditionMessage.forCondition(ConditionalOnProperty.class, new Object[]{spec}).because("matched")));

}

  

  

5、进入collectProperties方法

比较属性值是否匹配

private void collectProperties(PropertyResolver resolver, List<String> missing, List<String> nonMatching) {

    String[] var4 = this.names;

    int var5 = var4.length;


    for(int var6 = 0; var6 < var5; ++var6) {

        String name = var4[var6];

        String key = this.prefix + name;

        if(resolver.containsProperty(key)) {

            if(!this.isMatch(resolver.getProperty(key), this.havingValue)) {

                nonMatching.add(name);

            }

        } else if(!this.matchIfMissing) {

            missing.add(name);

        }

    }


}

最终通过equal判断是否匹配。

private boolean isMatch(String value, String requiredValue) {

         return StringUtils.hasLength(requiredValue)?requiredValue.equalsIgnoreCase(value):!"false".equalsIgnoreCase(value);

     }

  

 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值