我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小伙伴会觉得这个 Starter 好神奇呀!其实 Starter 也都是 Spring + SpringMVC 中的基础知识点实现的,今天松哥就来带大家自己来撸一个 Starter ,慢慢揭开 Starter 的神秘面纱!

核心知识

其实 Starter 的核心就是条件注解 @Conditional ,当 classpath 下存在某一个 Class 时,某个配置才会生效,前面松哥已经带大家学习过不少 Spring Boot 中的知识点,有的也涉及到源码解读,大伙可能也发现了源码解读时总是会出现条件注解,其实这就是 Starter 配置的核心之一,大伙有兴趣可以翻翻历史记录,看看松哥之前写的关于 Spring Boot 的文章,这里我就不再重复介绍了。

定义自己的 Starter

定义

所谓的 Starter ,其实就是一个普通的 Maven 项目,因此我们自定义 Starter ,需要首先创建一个普通的 Maven 项目,创建完成后,添加 Starter 的自动化配置类即可,如下:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>

配置完成后,我们首先创建一个 HelloProperties 类,用来接受 application.properties 中注入的值,如下:

@ConfigurationProperties(prefix = "javaboy")
public class HelloProperties {
private static final String DEFAULT_NAME = "江南一点雨";
private static final String DEFAULT_MSG = "牧码小子";
private String name = DEFAULT_NAME;
private String msg = DEFAULT_MSG;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

这个配置类很好理解,将 application.properties 中配置的属性值直接注入到这个实例中, @ConfigurationProperties 类型安全的属性注入,即将 application.properties 文件中前缀为 javaboy 的属性注入到这个类对应的属性上, 最后使用时候,application.properties 中的配置文件,大概如下:

javaboy.name=zhangsan
javaboy.msg=java

关注类型安全的属性注入,读者可以参考松哥之前的这篇文章:Spring Boot中的yaml配置简介,这篇文章虽然是讲 yaml 配置,但是关于类型安全的属性注入和 properties 是一样的。

配置完成 HelloProperties 后,接下来我们来定义一个 HelloService ,然后定义一个简单的 say 方法, HelloService 的定义如下:

public class HelloService {
private String msg;
private String name;
public String sayHello() {
return name + " say " + msg + " !";
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

这个很简单,没啥好说的。

接下来就是我们的重轴戏,自动配置类的定义,用了很多别人定义的自定义类之后,我们也来自己定义一个自定义类。先来看代码吧,一会松哥再慢慢解释:

@Configuration
@EnableConfigurationProperties(HelloProperties.class)
@ConditionalOnClass(HelloService.class)
public class HelloServiceAutoConfiguration {
@Autowired
HelloProperties helloProperties; @Bean
HelloService helloService() {
HelloService helloService = new HelloService();
helloService.setName(helloProperties.getName());
helloService.setMsg(helloProperties.getMsg());
return helloService;
}
}

关于这一段自动配置,解释如下:

  • 首先 @Configuration 注解表明这是一个配置类。
  • @EnableConfigurationProperties 注解是使我们之前配置的 @ConfigurationProperties 生效,让配置的属性成功的进入 Bean 中。
  • @ConditionalOnClass 表示当项目当前 classpath 下存在 HelloService 时,后面的配置才生效。
  • 自动配置类中首先注入 HelloProperties ,这个实例中含有我们在 application.properties 中配置的相关数据。
  • 提供一个 HelloService 的实例,将 HelloProperties 中的值注入进去。

做完这一步之后,我们的自动化配置类就算是完成了,接下来还需要一个 spring.factories 文件,那么这个文件是干嘛的呢?大家知道我们的 Spring Boot 项目的启动类都有一个 @SpringBootApplication 注解,这个注解的定义如下:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM,
classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}

大家看到这是一个组合注解,其中的一个组合项就是 @EnableAutoConfiguration ,这个注解是干嘛的呢?

@EnableAutoConfiguration 表示启用 Spring 应用程序上下文的自动配置,该注解会自动导入一个名为 AutoConfigurationImportSelector 的类,而这个类会去读取一个名为 spring.factories 的文件, spring.factories 中则定义需要加载的自动化配置类,我们打开任意一个框架的 Starter ,都能看到它有一个 spring.factories 文件,例如 MyBatis 的 Starter 如下:

那么我们自定义 Starter 当然也需要这样一个文件,我们首先在 Maven 项目的 resources 目录下创建一个名为 META-INF 的文件夹,然后在文件夹中创建一个名为 spring.factories 的文件,文件内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.javaboy.mystarter.HelloServiceAutoConfiguration

在这里指定我们的自动化配置类的路径即可。

如此之后我们的自动化配置类就算完成了。

本地安装

如果在公司里,大伙可能需要将刚刚写好的自动化配置类打包,然后上传到 Maven 私服上,供其他同事下载使用,我这里就简单一些,我就不上传私服了,我将这个自动化配置类安装到本地仓库,然后在其他项目中使用即可。安装方式很简单,在 IntelliJ IDEA 中,点击右边的 Maven Project ,然后选择 Lifecycle 中的 install ,双击即可,如下:

双击完成后,这个 Starter 就安装到我们本地仓库了,当然小伙伴也可以使用 Maven 命令去安装。

使用 Starter

接下来,我们来新建一个普通的 Spring Boot 工程,这个 Spring Boot 创建成功之后,加入我们自定义 Starter 的依赖,如下:

<dependency>
<groupId>org.javaboy</groupId>
<artifactId>mystarter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

此时我们引入了上面自定义的 Starter ,也即我们项目中现在有一个默认的 HelloService 实例可以使用,而且关于这个实例的数据,我们还可以在 application.properties 中进行配置,如下:

javaboy.name=牧码小子
javaboy.msg=java

配置完成后,方便起见,我这里直接在单元测试方法中注入 HelloSerivce 实例来使用,代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UsemystarterApplicationTests { @Autowired
HelloService helloService;
@Test
public void contextLoads() {
System.out.println(helloService.sayHello());
}
}

执行单元测试方法,打印日志如下:

好了,一个简单的自动化配置类我们就算完成了,是不是很简单!

总结

本文主要带领小伙伴自己徒手撸一个 Starter ,使用这种方式帮助大家揭开 Starter 的神秘面纱!大伙有问题可以留言讨论。

本文的案例,松哥已经上传到 GitHub上了,地址:https://github.com/lenve/javaboy-code-samples

关注公众号【江南一点雨】,专注于 Spring Boot+微服务以及前后端分离等全栈技术,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货!

Spring Boot2 系列教程(六)自定义 Spring Boot 中的 starter的更多相关文章

  1. Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源

    多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问 ...

  2. Spring Boot2 系列教程(三十)Spring Boot 整合 Ehcache

    用惯了 Redis ,很多人已经忘记了还有另一个缓存方案 Ehcache ,是的,在 Redis 一统江湖的时代,Ehcache 渐渐有点没落了,不过,我们还是有必要了解下 Ehcache ,在有的场 ...

  3. Spring Boot2 系列教程(十八)Spring Boot 中自定义 SpringMVC 配置

    用过 Spring Boot 的小伙伴都知道,我们只需要在项目中引入 spring-boot-starter-web 依赖,SpringMVC 的一整套东西就会自动给我们配置好,但是,真实的项目环境比 ...

  4. Spring Boot2 系列教程(二)创建 Spring Boot 项目的三种方式

    我最早是 2016 年底开始写 Spring Boot 相关的博客,当时使用的版本还是 1.4.x ,文章发表在 CSDN 上,阅读量最大的一篇有 43W+,如下图: 2017 年由于种种原因,就没有 ...

  5. Spring Boot2 系列教程(三十一)Spring Boot 构建 RESTful 风格应用

    RESTful ,到现在相信已经没人不知道这个东西了吧!关于 RESTful 的概念,我这里就不做过多介绍了,传统的 Struts 对 RESTful 支持不够友好 ,但是 SpringMVC 对于 ...

  6. Spring Boot2 系列教程(四)理解Spring Boot 配置文件 application.properties

    在 Spring Boot 中,配置文件有两种不同的格式,一个是 properties ,另一个是 yaml . 虽然 properties 文件比较常见,但是相对于 properties 而言,ya ...

  7. Spring Boot2 系列教程 (六) | 使用 JdbcTemplates 访问 Mysql

    前言 如题,今天介绍 springboot 通过jdbc访问关系型mysql,通过 spring 的 JdbcTemplate 去访问. 准备工作 SpringBoot 2.x jdk 1.8 mav ...

  8. Spring Boot2 系列教程(三)理解 Spring Boot 项目中的 parent

    前面和大伙聊了 Spring Boot 项目的三种创建方式,这三种创建方式,无论是哪一种,创建成功后,pom.xml 坐标文件中都有如下一段引用: <parent> <groupId ...

  9. Spring Boot2 系列教程(十九)Spring Boot 整合 JdbcTemplate

    在 Java 领域,数据持久化有几个常见的方案,有 Spring 自带的 JdbcTemplate .有 MyBatis,还有 JPA,在这些方案中,最简单的就是 Spring 自带的 JdbcTem ...

随机推荐

  1. vs2013 在按F5调试时,总是提示 “项目已经过期”的解决方案

    这个是由于缺少某些文件(如.h,xxx.icon),或者文件时间不对 引起的. 如图在工具选项设置 最小为 “诊断”. 然后编译一下,会提示 xxx过期,确认下即可.

  2. 基于vue手写tree插件那点事

    目录 iview提供的控件 手写控件 手写控件扩展 手写控件总结 # 加入战队 微信公众号 主题 Tree树形控件在前端开发中必不可少,对于数据的展示现在网站大都采取树形展示.因为大数据全部展示出来对 ...

  3. 使用Counter进行计数统计

    使用Counter进行计数统计 想必大家对计数统计都不陌生吧!,简单的说就是统计某一项出现的次数.实际应用中很多需求都需要用到这个模型,如检测样本中某一值出现的次数.日志分析某一消息出现的频率分析文件 ...

  4. 《Java 8 in Action》Chapter 6:用流收集数据

    1. 收集器简介 collect() 接收一个类型为 Collector 的参数,这个参数决定了如何把流中的元素聚合到其它数据结构中.Collectors 类包含了大量常用收集器的工厂方法,toLis ...

  5. ​综述 | SLAM回环检测方法

    本文作者任旭倩,公众号:计算机视觉life成员,由于格式原因,公式显示可能出问题,建议阅读原文链接:综述 | SLAM回环检测方法 在视觉SLAM问题中,位姿的估计往往是一个递推的过程,即由上一帧位姿 ...

  6. 章节十六、5-TestNG高级功能--Part2

    一.测试用例的依赖关系--->(dependsOnMethods = {"依赖方法名"}) 1.在实现自动化的过程中,有些测试用例必须在其它测试用例执行之后才能运行,两者之间 ...

  7. Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)

    Leetcode之回溯法专题-212. 单词搜索 II(Word Search II) 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单 ...

  8. 《Java 8 in Action》Chapter 9:默认方法

    传统上,Java程序的接口是将相关方法按照约定组合到一起的方式.实现接口的类必须为接口中定义的每个方法提供一个实现,或者从父类中继承它的实现. 但是,一旦类库的设计者需要更新接口,向其中加入新的方法, ...

  9. 基于ASP.Net Core开发的一套通用后台框架

    基于ASP.Net Core开发一套通用后台框架 写在前面 这是本人在学习的过程中搭建学习的框架,如果对你有所帮助那再好不过.如果您有发现错误,请告知我,我会第一时间修改. 知其然,知其所以然,并非重 ...

  10. NLP(二十一)根据已有文本LSTM自动生成文本

    根据已有文本LSTM自动生成文本 原理 与股票预测类似,用前面的n个字符预测下一个字符 https://www.cnblogs.com/peng8098/p/keras_5.html 代码 from ...