资讯专栏INFORMATION COLUMN

徒手撸一个 Spring Boot 中的 Starter ,解密自动化配置黑魔法!

xiaochao / 3116人阅读

摘要:先来看代码吧,一会松哥再慢慢解释关于这一段自动配置,解释如下首先注解表明这是一个配置类。本文的案例,松哥已经上传到上了,地址。

我们使用 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 的自动化配置类即可,如下:

org.springframework.boot spring-boot-autoconfigure 2.1.4.RELEASE

配置完成后,我们首先创建一个 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 的依赖,如下:

org.javaboy mystarter 1.0-SNAPSHOT

此时我们引入了上面自定义的 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上了,地址:github.com/lenve/javab… 。

关注公众号牧码小子,专注于 Spring Boot+微服务,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/6696.html

相关文章

  • Spring Cloud 升级最新 Finchley 版本,踩了所有的坑!

    摘要:因为默认开启了所有攻击防御,需要禁用的防御。版本变化有点大,本次已成功升级了基础依赖,及注册中心配置中心。其他像代替了及其他组件再慢慢升级,的快速发展令升级变得非常蛋疼,本文记录了升级过程中踩过的所有的坑。。。 Spring Boot 2.x 已经发布了很久,现在 Spring Cloud 也发布了 基于 Spring Boot 2.x 的 Finchley 版本,现在一起为项目做一次...

    WelliJhon 评论0 收藏0
  • 徒手框架--实现IoC

    摘要:从而能够进一步深入了解框架。至此我们框架开发完成。虽然说阅读源码是了解框架的最终手段。但是框架作为一个生产框架,为了保证通用和稳定,源码必定是高度抽象,且处理大量细节。下一篇文章应该会是徒手撸框架实现。 原文地址:https://www.xilidou.com/2018/... Spring 作为 J2ee 开发事实上的标准,是每个Java开发人员都需要了解的框架。但是Spring 的...

    rottengeek 评论0 收藏0
  • Maven 搭建spring boot多模块项目(附源码)

    摘要:搭建多模块项目备注所有项目都在中创建创建项目删除目录,只保留根目录可被子模块继承因此项目只是未考虑太多性能问题所以将诸多依赖都写在根级,子模块只需继承就可以使用。 Maven 搭建spring boot多模块项目 备注:所有项目都在idea中创建 1.idea创建maven项目 1-1: 删除src,target目录,只保留pom.xml 1-2: 根目录pom.xml可被子...

    whatsns 评论0 收藏0
  • SpringBoot 入门简介

    摘要:这里使用的是数据库启动类上加上注解在启动类中添加对包扫描扫描多个包下的可以有以下几种方法扫描会自动加载相关配置,数据源就会自动注入到中,会自动注入到中,可以直接使用。有配置文件下的使用扫描多个包下的可以有以下几种方法扫描 Spring-Boot 学习笔记 1 Spring-Boot 介绍 1.1 什么是Spring-Boot Spring-Boot是由Pivotal团队提供的全新框架...

    chuyao 评论0 收藏0
  • monkey-api-encrypt 1.1.2版本发布啦

    摘要:时隔多天,发布了第二个版本,还是要感谢一些正在使用的朋友们,提出了一些问题。配置文件可以在中使用可以在,中使用相同问题当存在两个相同的时,比如请求的和的请求。如果是使用的方式,框架会自动处理,会为每一个加上前缀来区分不同的请求方式。 时隔10多天,monkey-api-encrypt发布了第二个版本,还是要感谢一些正在使用的朋友们,提出了一些问题。 GitHub主页:https://g...

    blair 评论0 收藏0

发表评论

0条评论

xiaochao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<