SpringBoot场景启动器,你了解多少?

  • 在web.xml中注册SpringMVC的DispatcherServlet,并配置url映射

  • 编写springmcv-servlet.xml,在其中配置SpringMVC中几个重要的组件,处理映射器(HandlerMapping)、处理适配器(HandlerAdapter)、视图解析器(ViewResolver)

  • applicationcontext.xml文件中引入springmvc-servlet.xml文件

以上这几步只是配置好了SpringMVC,如果我们还需要与数据库进行交互,就要在application.xml中配置数据库连接池DataSource,如果需要数据库事务,还需要配置TransactionManager…

这就是使用Spring框架开发项目带来的一些的问题:

  • 依赖导入问题: 每个项目都需要来单独维护自己所依赖的jar包,在项目中使用到什么功能就需要引入什么样的依赖。手动导入依赖容易出错,且无法统一集中管理

  • 配置繁琐: 在引入依赖之后需要做繁杂的配置,并且这些配置是每个项目来说都是必要的,例如web.xml配置(Listener配置、Filter配置、Servlet配置)、log4j配置、数据库连接池配置等等。这些配置重复且繁杂,在不同的项目中需要进行多次重复开发,这在很大程度上降低了我们的开发效率

而在SpringBoot出现之后,它为我们提供了一个强大的功能来解决上述的两个痛点,这就是SpringBoot的starters(场景启动器)。

Spring Boot通过将我们常用的功能场景抽取出来,做成的一系列场景启动器,这些启动器帮我们导入了实现各个功能所需要依赖的全部组件,我们只需要在项目中引入这些starters,相关场景的所有依赖就会全部被导入进来,并且我们可以抛弃繁杂的配置,仅需要通过配置文件来进行少量的配置就可以使用相应的功能。

二、SpringBoot场景启动器的原理


在导入的starter之后,SpringBoot主要帮我们完成了两件事情:

  • 相关组件的自动导入

  • 相关组件的自动配置

这两件事情统一称为SpringBoot的自动配置

2.1 自动配置原理

2.1.1 自动配置类的获取与注入

我们从主程序入口来探索一下整个过程的原理:

@SpringBootApplication //标注这个类是一个springboot的应用

public class CommunityApplication {

public static void main(String[] args) {

//将springboot应用启动

SpringApplication.run(CommunityApplication.class, args);

}

}

@SpringBootApplication注解内部结构如下图所示:

AutoConfigurationImportSelector :重点看该类中重写的selectImports方法,看下它返回的字符串数组是如何得来的:

我们可以去到上边提到的spring.factories文件中去看一下,找到spring官方提供的spring-boot-autoconfigure包,在其下去找一下该文件:

可以看到这个就是SpringBoot官方为我们提供的所有自动配置类的候选列表。我们可以在其中找到一个我们比较熟悉的自动配置类去看一下它内部的实现:

可以看到这些一个个的都是JavaConfig配置类,而且都通过@Bean注解向容器中注入了一些Bean

结论:

  • SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的所有自动配置类的全限定类名

  • 将这些自动配置类导入容器,自动配置类就生效,帮我们进行自动配置工作;

  • 整个J2EE的整体解决方案和自动配置都在spring-boot-autoconfigure的jar包中;

  • 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件,并配置好这些组件 ;

  • 有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;

2.1.2 自动配置的过程

自动配置类被注入到容器当中后,会帮我们进行组件的自动配置和自动注入的工作,我们以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释这个过程:

首先我们先看下SpringBoot中配置文件与POJO类之间映射的方法,这是进行自动配置的基础。

配置集中化管理:SpringBoot中所有可配置项都集中在一个文件中(application.yml),这个文件中的配置通过@ConfigurationProperties注解来与我们程序内部定义的POJO类来产生关联,这些POJO类统一命名为xxxProperties,并且这些xxxProperties类中各个属性字段都有自己的默认值,这也是SpringBoot约定大于配置理念的体现,尽可能减少用户做选择的次数,但同时又不失灵活性。只要我们想,配置文件中的配置随时可以覆盖默认值。

之后,通过配合@EnableConfigurationProperties注解,就可以自动将与配置文件绑定好的这个类注入到容器中供我们使用。

自动配置类的工作流程:

  • 根据限定的条件向容器中注入组件

  • 使用xxxProperties对注入的组件的相关属性进行配置

//表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件;

@Configuration

//将与配置文件绑定好的某个类注入到容器中,使其生效

//进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;

//并把HttpProperties加入到ioc容器中

@EnableConfigurationProperties(HttpProperties.class)

//Spring底层@Conditional注解

//根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;

//这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效

@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)

//判断系统中有没有CharacterEncodingFilter这个类,如果有配置类才生效

@ConditionalOnClass(CharacterEncodingFilter.class)

//判断配置文件中是否存在某个配置:spring.http.encoding.enabled;

//matchIfMissing = true表明即使我们配置文件中不配置pring.http.encoding.enabled=true,该配置类也是默认生效的;

@ConditionalOnProperty(prefix = “spring.http.encoding”, value = “enabled”, matchIfMissing = true)

public class HttpEncodingAutoConfiguration {

//该类已经与配置文件绑定了

private final HttpProperties.Encoding properties;

//构建该自动配置类时将与配置文件绑定的配置类作为入参传递进去

public HttpEncodingAutoConfiguration(HttpProperties properties) {

this.properties = properties.getEncoding();

}

@Bean

@ConditionalOnMissingBean

public CharacterEncodingFilter characterEncodingFilter() {

CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();

filter.setEncoding(this.properties.getCharset().name()); //注入bean时使用配置类中属性的值进行初始化,相当于将配置文件中的值映射到了组件的某些属性上

filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));

filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));

return filter; //注入配置好的bean

}

}

一句话总结下自动配置类的工作过程 :

  • 首先容器会根据当前不同的条件判断,决定这个配置类是否生效!

  • 一但这个配置类生效;这个配置类就会给容器中添加相应组件;

  • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;

  • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着,配置文件可以配置什么内容,可以参照该前缀对应的属性类中的属性字段

//从配置文件中获取指定的值和bean的属性进行绑定

@ConfigurationProperties(prefix = “spring.http”)

public class HttpProperties {

// …

}

2.2 SpringBoot自动配置使用总结

  • SpringBoot启动会加载大量的自动配置类

  • 我们首先可以看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

  • 我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)

  • 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

    • xxxxAutoConfigurartion:自动配置类;给容器中添加组件
  • xxxxProperties:封装配置文件中相关属性;

了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置里面的所有内容才生效;

那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。

我们怎么知道哪些自动配置类生效?

我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

#在配置文件中开启springboot的调试类

debug=true

Positive matches:(自动配置类启用的:正匹配)

Positive matches:


AopAutoConfiguration matched:

- @ConditionalOnClass found required classes ‘org.springframework.context.annotation.EnableAspectJAutoProxy’, ‘org.aspectj.lang.annotation.Aspect’, ‘org.aspectj.lang.reflect.Advice’, ‘org.aspectj.weaver.AnnotatedElement’ (OnClassCondition)

- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)

AopAutoConfiguration.CglibAutoProxyConfiguration matched:

- @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)

AuditAutoConfiguration#auditListener matched:

- @ConditionalOnMissingBean (types: org.springframework.boot.actuate.audit.listener.AbstractAuditListener; SearchStrategy: all) did not find any beans (OnBeanCondition)

AuditAutoConfiguration#authenticationAuditListener matched:

- @ConditionalOnClass found required class ‘org.springframework.security.authentication.event.AbstractAuthenticationEvent’ (OnClassCondition)

- @ConditionalOnMissingBean (types: org.springframework.boot.actuate.security.AbstractAuthenticationAuditListener; SearchStrategy: all) did not find any beans (OnBeanCondition)

Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)

Negative matches:


ActiveMQAutoConfiguration:

Did not match:

- @ConditionalOnClass did not find required class ‘javax.jms.ConnectionFactory’ (OnClassCondition)

AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:

Did not match:

- @ConditionalOnProperty (spring.aop.proxy-target-class=false) did not find property ‘proxy-target-class’ (OnPropertyCondition)

AppOpticsMetricsExportAutoConfiguration:

Did not match:

- @ConditionalOnClass did not find required class ‘io.micrometer.appoptics.AppOpticsMeterRegistry’ (OnClassCondition)

ArtemisAutoConfiguration:

Did not match:

- @ConditionalOnClass did not find required class ‘javax.jms.ConnectionFactory’ (OnClassCondition)

Exclusions、Unconditional classes(排除的、没有限定条件的自动配置类):

Exclusions:


org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

Unconditional classes:


org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration

org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration

org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration

org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration

三、自定义场景启动器


现在我们已经了解了场景启动器的概念以及其隐藏在背后的自动配置的原理,我们就可以自己来对SpringBoot进行功能拓展,定义我们自己的场景启动器。另外,欢迎关注公众号Java笔记虾,后台回复“后端面试”,送你一份面试题宝典!

3.1 starter的命名规范

官方命名空间

  • 前缀:spring-boot-starter-

  • 模式:spring-boot-starter-模块名

  • 举例:spring-boot-starter-web、spring-boot-starter-jdbc

自定义命名空间

  • 后缀:-spring-boot-starter

  • 模式:模块-spring-boot-starter

  • 举例:mybatis-spring-boot-starter

3.2 starter模块整体结构

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

权威指南-第一本Docker书

引领完成Docker的安装、部署、管理和扩展,让其经历从测试到生产的整个开发生命周期,深入了解Docker适用于什么场景。并且这本Docker的学习权威指南介绍了其组件的基础知识,然后用Docker构建容器和服务来完成各种任务:利用Docker为新项目建立测试环境,演示如何使用持续集成的工作流集成Docker,如何构建应用程序服务和平台,如何使用Docker的API,如何扩展Docker。

总共包含了:简介、安装Docker、Docker入门、使用Docker镜像和仓库、在测试中使用Docker、使用Docker构建服务、使用Fig编配Docke、使用Docker API、获得帮助和对Docker进行改进等9个章节的知识。

image

image

image

image

关于阿里内部都在强烈推荐使用的“K8S+Docker学习指南”—《深入浅出Kubernetes:理论+实战》、《权威指南-第一本Docker书》,看完之后两个字形容,爱了爱了!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
础知识,然后用Docker构建容器和服务来完成各种任务:利用Docker为新项目建立测试环境,演示如何使用持续集成的工作流集成Docker,如何构建应用程序服务和平台,如何使用Docker的API,如何扩展Docker。

总共包含了:简介、安装Docker、Docker入门、使用Docker镜像和仓库、在测试中使用Docker、使用Docker构建服务、使用Fig编配Docke、使用Docker API、获得帮助和对Docker进行改进等9个章节的知识。

[外链图片转存中…(img-ZROlPdK9-1713406218116)]

[外链图片转存中…(img-ph5LnMNo-1713406218116)]

[外链图片转存中…(img-dUbPvyqe-1713406218117)]

[外链图片转存中…(img-rksTs9O1-1713406218117)]

关于阿里内部都在强烈推荐使用的“K8S+Docker学习指南”—《深入浅出Kubernetes:理论+实战》、《权威指南-第一本Docker书》,看完之后两个字形容,爱了爱了!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值