企业级spring-boot案例-自定义Spring Boot Starter

2.3 Spring 官方提供的 Starter 和 Starter 命名规范

SpringBoot 提供了非常多的 Starter,下面列出常用的几个:

| 序号 | 名称 | 功能 |

| — | — | — |

| 1 | spring-boot-starter-web | 支持 Web 开发,包括 Tomcat 和 spring-webmvc |

| 2 | spring-boot-starter-redis | 支持 Redis 键值存储数据库,包括 spring-redis |

| 3 | spring-boot-starter-test | 支持常规的测试依赖,包括 JUnit、Hamcrest、Mockito 以及 spring-test 模块 |

| 4 | spring-boot-starter-aop | 支持面向切面的编程即 AOP,包括 spring-aop 和 AspectJ |

| 5 | spring-boot-starter-data-elasticsearch | 支持 ElasticSearch 搜索和分析引擎,包括 spring-data-elasticsearch |

| 6 | spring-boot-starter-jdbc | 支持JDBC数据库 |

| 7 | spring-boot-starter-data-jpa | 支持 JPA ,包括 spring-data-jpa、spring-orm、Hibernate |

可以看到这些 Starter 的名称都是以 spring-boot-starter 为开头,后面跟着具体的模块名,所有官方的 Starter 遵循相似的命名模式。

根据约定,Spring Boot官方的starter命名要定义为spring-boot-starter-*,自定义或者说第三方的要命名为thirdpartyproject-spring-boot-starter

  • 官方命名空间

  • 前缀:spring-boot-starter-

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

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

  • 自定义命名空间

  • 后缀:-spring-boot-starter

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

  • 举例:mybatis-spring-boot-starter

3. 自定义Spring Boot Starter


如果你想要自己创建一个 starter,那么基本上包含以下几步

3.1 根据 starter 命名规范创建一个 spring boot 项目

创建一个名为config-spring-boot-starter的 spring boot 项目

3.2 在 pom.xml 文件中引入依赖

org.springframework.boot

spring-boot-autoconfigure

org.springframework.boot

spring-boot-configuration-processor

true

org.projectlombok

lombok

true

3.3 编写ConfigInfo.javaConfigService.javaConfigServiceImpl.java

ConfigInfo 配置信息类,用于封装配置信息。

@Data

@Builder

public class ConfigInfo implements Serializable {

private static final long serialVersionUID = -2878523532668902073L;

/**

  • ID

*/

private String id;

/**

  • IP地址

*/

private String ip;

}

ConfigService 示例业务接口,这里我们定义了一个configInfo接口,用于获取配置信息。

public interface ConfigService {

/**

  • 获取配置信息

  • @return {@link ConfigInfo}

*/

ConfigInfo configInfo();

}

ConfigServiceImpl 业务逻辑实现类,用于实现功能。

public class ConfigServiceImpl implements ConfigService {

/**

  • ID

*/

private String id;

/**

  • ip

*/

private String ip;

/**

  • 构造函数

  • @param id ID

  • @param ip IP

*/

public ConfigServiceImpl(String id, String ip) {

this.id = id;

this.ip = ip;

}

/**

  • 获取配置信息

  • @return {@link ConfigInfo}

*/

@Override

public ConfigInfo configInfo() {

return ConfigInfo.builder().id(this.id).ip(this.ip).build();

}

}

3.4 编写ConfigProperties.java

创建一个配置文件读取类 ConfigurationProperties 用于保存配置信息(如果你的项目不使用配置信息则可以跳过这一步,不过这种情况非常少见)

@ConfigurationProperties注解使开发人员可以轻松地将整个文件.propertiesyml文件映射到一个对象中。编写Properties,应使用唯一的名称空间。不要使用Spring Boot的名称空间(如server,management,spring等)。所以应在所有配置键前面加上自己的名称空间。如我们这里使用的是com.jourwon.config作为配置名称空间。

@Data

@ConfigurationProperties(value = “com.jourwon.config”)

public class ConfigProperties {

/**

  • ID标识

*/

private String id;

/**

  • IP地址

*/

private String ip;

}

3.5 编写ConfigAutoConfiguration.java

创建一个 AutoConfiguration,编写带有@Configuration的配置类,并添加@EnableConfigurationProperties注解,@EnableConfigurationProperties作用是为了使@ConfigurationProperties注解的类生效。

@Slf4j

@Configuration

@EnableConfigurationProperties(value = ConfigProperties.class)

public class ConfigAutoConfiguration {

@Resource

private ConfigProperties properties;

/**

  • 配置ExampleService

  • @return {@link ConfigService}

*/

@Bean

@ConditionalOnMissingBean

public ConfigService configService() {

log.info(“Config ConfigService Start…”);

ConfigService service = new ConfigServiceImpl(properties.getId(), properties.getIp());

log.info(“Config ConfigService End.”);

return service;

}

}

3.6 编写spring.factories

resources/META-INF/下创建spring.factories文件,并且把上一步创建的AutoConfiguration类加入 spring.factories 配置文件中

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

com.jourwon.spring.boot.config.ConfigAutoConfiguration

3.7 发布自定义 starter

在自定义 starter 项目根目录执行 mvn install 进行打包安装

3.8 测试自定义 starter

3.8.1 添加config-spring-boot-starter依赖

<config-spring-boot-starter.version>1.0.0</config-spring-boot-starter.version>

com.jourwon.spring.boot

config-spring-boot-starter

${config-spring-boot-starter.version}

org.springframework.boot

spring-boot-starter-web

com.alibaba

fastjson

3.8.2 配置application.yml

IDE 提示

在使用官方starter的时候,我们可以发现IDE可以进行提示

在这里插入图片描述

application.yml配置文件添加如下配置

自定义starter相关配置

com:

jourwon:

config:

id: 23145fdb-7427-42d1-ae29-a67f5be30d02

ip: 127.0.0.1

3.8.3 编写 ConfigInfoController.java

@RestController

public class ConfigInfoController {

@Resource

private ConfigService configService;

@GetMapping(“/configInfo”)

public String configInfo() {

return JSON.toJSONString(configService.configInfo());

}

}

3.8.4 启动测试

打开浏览器,输入 http://127.0.0.1:8080/configInfo ,你将会看到我们配置的内容。

在这里插入图片描述

4. Spring Boot Starter原理


首先说说原理,我们知道使用一个公用的starter的时候,只需要将相应的依赖添加的Maven的配置文件当中即可,免去了自己需要引用很多依赖类,并且SpringBoot会自动进行类的自动配置。

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

  • 相关组件的自动导入

  • 相关组件的自动配置

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

那么 SpringBoot 是如何知道要实例化哪些类,并进行自动配置的呢? 下面简单说一下。

首先,SpringBoot 在启动时会去依赖的starter包中寻找 resources/META-INF/spring.factories文件,然后根据文件中配置的Jar包去扫描项目所依赖的Jar包,这类似于 Java 的 SPI 机制。

第二步,根据 spring.factories配置加载AutoConfigure类。

最后,根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context 上下文当中。

我们也可以使用@ImportAutoConfiguration({MyServiceAutoConfiguration.class}) 指定自动配置哪些类。

4.1 自动配置原理

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

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

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

@SpringBootApplication

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), 就是给容器中导入这个场景需要的所有组件,并配置好这些组件 ;

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

4.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表明即使我们配置文件中不配置spring.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();

//注入bean时使用配置类中属性的值进行初始化,相当于将配置文件中的值映射到了组件的某些属性上

filter.setEncoding(this.properties.getCharset().name());

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

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

//注入配置好的bean

return filter;

}

}

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

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

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

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

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

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

img

总结

就写到这了,也算是给这段时间的面试做一个总结,查漏补缺,祝自己好运吧,也希望正在求职或者打算跳槽的 程序员看到这个文章能有一点点帮助或收获,我就心满意足了。多思考,多问为什么。希望小伙伴们早点收到满意的offer! 越努力越幸运!

金九银十已经过了,就目前国内的面试模式来讲,在面试前积极的准备面试,复习整个 Java 知识体系将变得非常重要,可以很负责任的说一句,复习准备的是否充分,将直接影响你入职的成功率。但很多小伙伴却苦于没有合适的资料来回顾整个 Java 知识体系,或者有的小伙伴可能都不知道该从哪里开始复习。我偶然得到一份整理的资料,不论是从整个 Java 知识体系,还是从面试的角度来看,都是一份含技术量很高的资料。

三面蚂蚁核心金融部,Java开发岗(缓存+一致性哈希+分布式)

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
[外链图片转存中…(img-RKhCrx3s-1713515563635)]

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

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

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

img

总结

就写到这了,也算是给这段时间的面试做一个总结,查漏补缺,祝自己好运吧,也希望正在求职或者打算跳槽的 程序员看到这个文章能有一点点帮助或收获,我就心满意足了。多思考,多问为什么。希望小伙伴们早点收到满意的offer! 越努力越幸运!

金九银十已经过了,就目前国内的面试模式来讲,在面试前积极的准备面试,复习整个 Java 知识体系将变得非常重要,可以很负责任的说一句,复习准备的是否充分,将直接影响你入职的成功率。但很多小伙伴却苦于没有合适的资料来回顾整个 Java 知识体系,或者有的小伙伴可能都不知道该从哪里开始复习。我偶然得到一份整理的资料,不论是从整个 Java 知识体系,还是从面试的角度来看,都是一份含技术量很高的资料。

[外链图片转存中…(img-RR5ehV4f-1713515563635)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值