一, 码前必备知识
1,SpringBoot starter 机制
SpringBoot 中的 starter 是一种非常重要的机制, 能够抛弃以前繁杂的配置, 将其统一集成进 starter, 应用者只需要在 maven 中引入 starter 依赖, SpringBoot 就能自动扫描到要加载的信息并启动相应的默认配置. starter 让我们摆脱了各种依赖库的处理, 需要配置各种信息的困扰. SpringBoot 会自动通过 classpath 路径下的类发现需要的 Bean, 并注册进 IoC 容器. SpringBoot 提供了针对日常企业应用研发各种场景的 spring-boot-starter 依赖模块. 所有这些依赖模块都遵循着约定成俗的默认配置, 并允许我们调整这些配置, 即遵循 "约定大于配置" 的理念.
2, 为什么要自定义 starter
在我们的日常开发工作中, 经常会有一些独立于业务之外的配置模块, 我们经常将其放到一个特定的包下, 然后如果另一个工程需要复用这块功能的时候, 需要将代码硬拷贝到另一个工程, 重新集成一遍, 麻烦至极. 如果我们将这些可独立于业务代码之外的功配置模块封装成一个个 starter, 复用的时候只需要将其在 pom 中引用依赖即可, SpringBoot 为我们完成自动装配, 简直不要太爽.
3, 自定义 starter 的案例
以下案例由笔者工作中遇到的部分场景
▲ 动态数据源.
▲ 登录模块.
▲ 基于 AOP 技术实现日志切面.
......
4, 自定义 starter 的命名规则
SpringBoot 提供的 starter 以 spring-boot-starter-xxx 的方式命名的. 官方建议自定义的 starter 使用 xxx-spring-boot-starter 命名规则. 以区分 SpringBoot 生态提供的 starter.
二, starter 的实现方法
1, 新建一个工程
命名为 demo-spring-boot-starter
下图为工程目录结构
2,pom 依赖
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.1.4.RELEASE</version>
- </parent>
- <groupId>com.demo</groupId>
- <artifactId>demo-spring-boot-starter</artifactId>
- <version>0.0.1-RELEASE</version>
- <name>demo-spring-boot-starter</name>
- <description>Demo project for Spring Boot</description>
- <properties>
- <java.version>1.8</java.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
- </dependencies>
- </project>
3, 定义一个实体类映射配置信息
@ConfigurationProperties(prefix = "demo") 它可以把相同前缀的配置信息通过配置项名称映射成实体类, 比如我们这里指定 prefix = "demo" 这样, 我们就能将以 demo 为前缀的配置项拿到了.
ps: 其实这个注解很强大, 它不但能映射简单的 key-value 的形式. 还可以映射为 List,Map 等数据结构.
- package com.demo.starter.properties;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- /**
- * 描述: 配置信息 实体
- *
- * @Author shf
- * @Date 2019/5/7 22:08
- * @Version V1.0
- **/
- @ConfigurationProperties(prefix = "demo")
- public class DemoProperties {
- private String sayWhat;
- private String toWho;
- public String getSayWhat() {
- return sayWhat;
- }
- public void setSayWhat(String sayWhat) {
- this.sayWhat = sayWhat;
- }
- public String getToWho() {
- return toWho;
- }
- public void setToWho(String toWho) {
- this.toWho = toWho;
- }
- }
4, 定义一个 Service
- package com.demo.starter.service;
- /**
- * 描述: 随便定义一个 Service
- *
- * @Author shf
- * @Date 2019/5/7 21:59
- * @Version V1.0
- **/
- public class DemoService {
- public String sayWhat;
- public String toWho;
- public DemoService(String sayWhat, String toWho){
- this.sayWhat = sayWhat;
- this.toWho = toWho;
- }
- public String say(){
- return this.sayWhat + "!" + toWho;
- }
- }
5, 定义一个配置类
这里, 我们将 DemoService 类定义为一个 Bean, 交给 IoC 容器.
▲ @Configuration 注解就不多说了.
▲ @EnableConfigurationProperties 注解. 该注解是用来开启对 3 步骤中 @ConfigurationProperties 注解配置 Bean 的支持. 也就是 @EnableConfigurationProperties 注解告诉 Spring Boot 能支持 @ConfigurationProperties.
当然了, 也可以在 @ConfigurationProperties 注解的类上添加 @Configuration 或者 @Component 注解
▲ @ConditionalOnProperty 注解控制 @Configuration 是否生效. 简单来说也就是我们可以通过在 YAML 配置文件中控制 @Configuration 注解的配置类是否生效.
- package com.demo.starter.config;
- import com.demo.starter.properties.DemoProperties;
- import com.demo.starter.service.DemoService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
- import org.springframework.boot.context.properties.EnableConfigurationProperties;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- /**
- * 描述: 配置类
- *
- * @Author shf
- * @Date 2019/5/7 21:50
- * @Version V1.0
- **/
- @Configuration
- @EnableConfigurationProperties(DemoProperties.class)
- @ConditionalOnProperty(
- prefix = "demo",
- name = "isopen",
- havingValue = "true"
- )
- public class DemoConfig {
- @Autowired
- private DemoProperties demoProperties;
- @Bean(name = "demo")
- public DemoService demoService(){
- return new DemoService(demoProperties.getSayWhat(), demoProperties.getToWho());
- }
- }
6, 最重要的来了
如图, 新建 META-INF 文件夹, 然后创建 spring.factories 文件,
在该文件中加入如下配置, 该配置指定上步骤中定义的配置类为自动装配的配置.(笔者努力最近把自动装配的博客写出来)
- #-------starter 自动装配 ---------
- org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.demo.starter.config.DemoConfig
7, 测试
在 demo-spring-boot-starter 工程中执行 mvn clean install 一个自定义的 starter 新鲜出炉.
新建测试工程
引入 starter 依赖
- <dependency>
- <groupId>com.demo</groupId>
- <artifactId>demo-spring-boot-starter</artifactId>
- <version>0.0.1-RELEASE</version>
- </dependency>
配置文件
- demo.isopen=true
- demo.say-what=hello
- demo.to-who=shf
然后写个测试类.
- package com.example.test.controller;
- import com.demo.starter.service.DemoService;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.Web.bind.annotation.RestController;
- import javax.annotation.Resource;
- /**
- * 描述:
- *
- * @Author shf
- * @Description TODO
- * @Date 2019/5/13 15:52
- * @Version V1.0
- **/
- @RestController
- public class DemoController {
- @Resource(name = "demo")
- private DemoService demoService;
- @GetMapping("/say")
- public String sayWhat(){
- return demoService.say();
- }
- }
浏览器
来源: https://www.cnblogs.com/hello-shf/p/10864977.html