手把手教你开发SpringBoot starter

前言:
SpringBoot在java中的地位简直是至尊的存在,非常的好用。Spring Boot有四大神器,分别是auto-configuration、starters、cli、actuator,我们用各种中间件的话就是各种starter 对应版本依赖引用,然后就是配置属性文件,就可以用了,其实工作当中,我们可以把一些通用的方法,服务来封装成starter,本文来交大家进行手动实现一个starter,满足我们以后工作的需要。

1.源码中的starter和自动配置:
Spring boot开发的时候我们不需要像Springmvc一样各种xml的各种配置写,开箱即用。看源码的话发现这个实现是基于:spring-boot-autoconfigure依赖。里面包含了很多其他的依赖包:看图:

图片

看源码里面都有个一个xxxxAAutoConfiguration的类:rabbitmq:

图片

其中注解说明:

1.@Configuration注解表示这是一个配置类,用过Spring Boot的朋友都应该知道是什么东西,不多做解释了。

2.@ConditionalOnClass({RabbitTemplate.class, Channel.class}),该注解表示当KafkaTemplate.class被加载到JVM中,才会对配置类进行初始化,简单理解就是把他当做if语句来看。

3.@EnableConfigurationProperties({RabbitProperties.class}),加载属性配置类的注解,有这个注解,KafkaProperties才会作用于应用上下文中。

4.@Import({RabbitAnnotationDrivenConfiguration.class}),Spring 的基础注解,不多说了。Spring boot是通过两个路径来确定自动配置类的,一个是@EnableAutoConfiguration注解,二是spring.factories配置文件,改文件在META-INF目录下面,里面配置了配置项:org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration。

@SpringBootApplication注解是包含@EnableAutoConfiguration注解的,注解里面的核心注解是:@Import(AutoConfigurationImportSelector.class)注解,里面涉及到代码:

protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); Assert.notEmpty(configurations, “No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.”);
return configurations;
}
就是加载资源配置文件。

流程总结的话就是:应用配置类注解@EnableAutoConfiguration-》导入AutoConfigurationImportSelector-》启动应用加载spring.factories里的配置信息(通过AutoConfigurationImportSelector 、getCandidateConfigurations)-》如果缺少相关依赖类存在,就不会触发执行,触发成功,就会执行。其中spring.factories不仅仅包含自动配置相关信息,还包含其他的信息。

2.手动实现starter:
我们用springboot的时候加入spring-boot-starter-web依赖,不需要任何配置,就可以直接构建web应用,可见自动配置的厉害,spring是一个扩展性很强的框架,支持我们自定义符合需求的starter。

一个完整的starter包含两个部分:1.提供自动配置功能的自动配置模块

2.做到开箱即用,提供依赖关系管理的组件模块

spring-boot-autoconfigure中包含的AutoConfiguration都是Spring家族的项目,自己封装的starter就需要自己写xxxAutoConfiguration。

添加依赖:

org.springframework.boot spring-boot-autoconfigure 导入配置代码:

@ConfigurationProperties(prefix = “yeonon.car”)public class CarProperties { private static final String DEFAULT_NAME = “BWM”; private static final String DEFAULT_COLOR = “white”; private static final Integer DEFAULT_AGE = 1; private String name = DEFAULT_NAME; private String color = DEFAULT_COLOR; private Integer age = DEFAULT_AGE; public String getName() { return name;
} public void setName(String name) { this.name = name;
} public String getColor() { return color;
} public void setColor(String color) { this.color = color;
} public Integer getAge() { return age;
} public void setAge(Integer age) { this.age = age;
} //getter 和 setter必须要有,否则属性注入会有问题}
service代码:

public class CarService {

private Car car;    public Car getCar() {        return car;
}    public void setCar(Car car) {        this.car = car;
}

}
自动配置类

@Configuration
@ConditionalOnClass(CarService.class)@EnableConfigurationProperties(value = CarProperties.class)public class CarAutoConfiguration {

@Autowired    private CarProperties carProperties;

@Bean
@ConditionalOnMissingBean(CarService.class)//    @ConditionalOnProperty(value = "yeonon.car.server.configuration.auto.enabled", matchIfMissing = true)
public CarService carService() {
    CarService carService = new CarService();
    Car car = new Car();
    car.setName(carProperties.getName());
    car.setColor(carProperties.getColor());
    car.setAge(carProperties.getAge());
    carService.setCar(car);
    return carService;
}

}
注解说明:@Configuration注解是要有的,否则无法生效。

@ConditionalOnClass(CarService.class),原则上可有可无,但作为一个健壮的starter,还是有的好,作为一个“防御措施”。

@EnableConfigurationProperties(value = CarProperties.class),要使用属性系统,就需要把属性类加入到应用上下文中。

@Bean就是定义一个Bean了,代码逻辑没什么可说的,无法就是创建对象,然后构建对象并返回而已。关键在于@ConditionalOnMissingBean注解和@ConditionalOnProperty注解。@ConditionalOnMissingBean注解的意思就是如果应用中不存在CarService的Bean,那么就执行下面的方法构建一个Bean,已经存在的话,就不会调用下面的方法了,这意味着用户可以自己创建Bean来覆盖系统默认配置的Bean。@ConditionalOnProperty就是当配置存在的时候,才会执行Bean的构建。

然后再资源文件夹下面创建META-INF文件夹,创建spring.factories,配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
top.yeonon.stater.test.CarAutoConfiguration
应用starter:

@Autowired
private CarService carService;
@GetMapping(“car”)
public Car getMyCar(@AutoLoginInfo LoginInfo loginInfo, @AutoUserInfo UserInfo userInfo) { System.out.println(loginInfo); System.out.println(userInfo); return carService.getCar();
}
属性配置:

注意前缀是yeonon.car,也是在CarProperties类里配置好的yeonon.car.name=MSLD

yeonon.car.age=2
yeonon.car.color=black
总结
上面的手动实现starter其实是一个标准的实现过程,但是呢,我们实际开发其实并不需要那么麻烦,两个注解搞定starter,第一个注解@EnableMonitor注解在springboot启动类上,然后里面的注解实现:

@Documented@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})@Import({MetricsConfig.class, MonitorConfig.class})
public @interface EnableMonitor {
}
这样分别在Import里面的类去实现业务逻辑就可以。如果你有问题换用留言,如果你喜欢欢迎点赞,转发,赞赏。

热门文章

暂无图片
编程学习 ·

C语言二分查找详解

二分查找是一种知名度很高的查找算法,在对有序数列进行查找时效率远高于传统的顺序查找。 下面这张动图对比了二者的效率差距。 二分查找的基本思想就是通过把目标数和当前数列的中间数进行比较,从而确定目标数是在中间数的左边还是右边,将查…
暂无图片
编程学习 ·

GMX 命令分类列表

建模和计算操作命令: 1.1 . 创建拓扑与坐标文件 gmx editconf - 编辑模拟盒子以及写入子组(subgroups) gmx protonate - 结构质子化 gmx x2top - 根据坐标生成原始拓扑文件 gmx solvate - 体系溶剂化 gmx insert-molecules - 将分子插入已有空位 gmx genconf - 增加…
暂无图片
编程学习 ·

一文高效回顾研究生课程《数值分析》重点

数值分析这门课的本质就是用离散的已知点去估计整体,就是由黑盒子产生的结果去估计这个黑盒子。在数学里这个黑盒子就是一个函数嘛,这门课会介绍许多方法去利用离散点最大化地逼近这个函数,甚至它的导数、积分,甚至微分方程的解。…
暂无图片
编程学习 ·

在职阿里5年,一个28岁女软测工程师的心声

简单的先说一下,坐标杭州,14届本科毕业,算上年前在阿里巴巴的面试,一共有面试了有6家公司(因为不想请假,因此只是每个晚上去其他公司面试,所以面试的公司比较少) ​ 编辑切换为居中…
暂无图片
编程学习 ·

字符串左旋c语言

目录 题目: 解题思路: 第一步: 第二步: 第三步: 总代码: 题目: 实现一个函数,可以左旋字符串中的k个字符。 例如: ABCD左旋一个字符得到BCDA ABCD左旋两个字符…
暂无图片
编程学习 ·

设计模式--观察者模式笔记

模式的定义与特点 观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式&#xf…
暂无图片
编程学习 ·

睡觉突然身体动不了,什么是睡眠痽痪症

很多朋友可能有这样的体验,睡觉过程中突然意识清醒,身体却动弹不了。这时候感觉非常恐怖,希望旁边有一个人推自己一下。阳光以前也经常会碰到这样的情况,一年有一百多次,那时候很害怕晚上到来,睡觉了就会出…
暂无图片
编程学习 ·

深入理解C++智能指针——浅析MSVC源码

文章目录unique_ptrshared_ptr 与 weak_ptrstd::bad_weak_ptr 异常std::enable_shared_from_thisunique_ptr unique_ptr 是一个只移型别(move-only type,只移型别还有std::mutex等)。 结合一下工厂模式,看看其基本用法&#xff…
暂无图片
编程学习 ·

@TableField(exist = false)

TableField(exist false) //申明此字段不在数据库存在,但代码中需要用到它,通知Mybatis-plus在做写库操作是忽略它。,.
暂无图片
编程学习 ·

Java Web day15

第十二章文件上传和下载 一、如何实现文件上传 要实现Web开发中的文件上传功能,通常需要完成两步操作:一.是在Web页面中添加上传输入项;二是在Servlet中读取上传文件的数据,并保存到本地硬盘中。 需要使用一个Apache组织提供一个…
暂无图片
编程学习 ·

【51nod 2478】【单调栈】【前缀和】小b接水

小b接水题目解题思路Code51nod 2478 小b接水 题目 输入样例 12 0 1 0 2 1 0 1 3 2 1 2 1输出样例 6解题思路 可以发现最后能拦住水的都是向两边递减高度(?) 不管两个高积木之间的的积木是怎样乱七八糟的高度,最后能用来装水的…
暂无图片
编程学习 ·

花了大半天写了一个UVC扩展单元调试工具

基于DIRECTSHOW 实现的,用的是MFC VS2019. 详见:http://www.usbzh.com/article/detail-761.html 获取方法 加QQ群:952873936,然后在群文件\USB调试工具&测试软件\UVCXU-V1.0(UVC扩展单元调试工具-USB中文网官方版).exe USB中文网 USB中文…
暂无图片
编程学习 ·

贪心(一):区间问题、Huffman树

区间问题 例题一:区间选点 给定 N 个闭区间 [ai,bi]请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。 输出选择的点的最小数量。 位于区间端点上的点也算作区间内。 输入格式 第一行包含整数 N,表示区间数。 接下来 …
暂无图片
编程学习 ·

C语言练习实例——费氏数列

目录 题目 解法 输出结果 题目 Fibonacci为1200年代的欧洲数学家,在他的着作中曾经提到:「若有一只免子每个月生一只小免子,一个月后小免子也开始生产。起初只有一只免子,一个月后就有两只免子,二个月后有三只免子…
暂无图片
编程学习 ·

Android开发(2): Android 资源

个人笔记整理 Android 资源 Android中的资源,一般分为两类: 系统内置资源:Android SDK中所提供的已经定义好的资源,用户可以直接拿来使用。 用户自定义资源:用户自己定义或引入的,只适用于当前应用的资源…
暂无图片
编程学习 ·

零基础如何在短时间内拿到算法offer

​算法工程师是利用算法处理事物的职业 算法(Algorithm)是一系列解决问题的清晰指令,也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。 如果一个算法有缺陷,或不适合于某个问题,执…
暂无图片
编程学习 ·

人工智能:知识图谱实战总结

人工智能python,NLP,知识图谱,机器学习,深度学习人工智能:知识图谱实战前言一、实体建模工具Protegepython,NLP,知识图谱,机器学习,深度学习 人工智能:知识图…
暂无图片
编程学习 ·

【无标题】

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…