SpringBoot自定义Starter(二十四)上

简介: 一. 自定义Starter 基础知识一.一 自定义Starter一.二 自定义Starter 需要什么二. 实现用户信息打印的 自定义 Starter二.一 pom.xml 导入依赖二.三 做什么, 要实现的功能二.四 动态热插拔配置二.五 配置,能被 SpringBoot 官方承认二.六 测试自定义 Starter

一. 自定义Starter 基础知识

一.一 自定义Starter

以前我们在学习 Spring 时,依赖的依赖,都是某一个具体的依赖信息。在Spring Boot 阶段,我们导入的依赖 的 artifactId 都拥有 starter。如: mybatis-spring-boot-starter pagehelper-spring-boot-starter 等.

这些其实,都是比较官方的自定义 Starter。

在日常开发里面,对于独立于业务模块的一些功能,常常会放置在一个单独的包里,

如 切面实现日志功能, 在项目A里面使用到了,在项目B 里面也使用到了,以前的做法,是什么样子的呢? 通常将这个日志功能实现的代码复制A项目里面,同时复制到B项目里面,这样 A项目便拥有了日志的功能,B项目也拥有了日志的功能。如果实现日志功能的代码发生改变,那么项目A,项目B都需要进行修改。如果能够将 这个切面实现日志功能的代码 提取出来,变成一个 依赖的jar包,项目A,项目B直接导入依赖,便可以使用,那就好了。

我们可以通过自定义Starter 实现这些功能。

SpringBoot提供的starter以spring-boot-starter-xxx的方式命名的。

官方建议自定义的starter使用xxx-spring-boot-starter命名规则。以区分SpringBoot生态提供的starter。

这一章节,先简单实现一个基础的自定义Starter 的功能。

下一章节,老蝴蝶带着大家通过自定义 Starter 实现切面日志记录的功能。

一.二 自定义Starter 需要什么

我们自定义 Starter 需要什么呢? 想一想,以前的配置, 如 redis的配置,mysql数据库的配置信息.

1.我们需要传入一些参数,可以更改配置 (在application.yml 中配置参数) ,同时有默认的配置参数.

2.有一个功能实现,可以获取到用户传入的配置参数,使用这些配置参数,可以实现我们想要的功能.

3.动态的进行配置,热插拔效果。达到 我们拥有这个自定义starter,就拥有这些东西,没有自定义starter,就没有这些东西的效果。

4.自动化的配置,可以被 SpringBoot 官方识别并承认 (需要固定的格式).

我们需要拥有这些东西,才可以进行自定义 Starter

二. 实现用户信息打印的 自定义 Starter

先创建一个默认的 Maven 项目, 非 SpringBoot 项目。

主要依靠的是 SpringBoot 的自动配置

我们做一个简单的,配置信息打印的 Starter

18.png

1,2,3,4 其实对应的就是 一.二 部分的 1,2,3,4

二.一 pom.xml 导入依赖

<?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>
    <groupId>top.yueshushu</groupId>
    <artifactId>starter</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>ButterflyStarter</name>
    <dependencies>
        <!--添加自动配置的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
        <!--添加配置文件引用的依赖信息-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>2.2.2.RELEASE</version>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>

除些之外,不需要引入其他的.

二.二 属性类接收用户自定义参数

在 application.yml 中配置参数,通常有很多个,且格式固定, 我们常常通过一个配置属性类进行接收用户的自定义参数。我们传入 名称,年龄,描述 三个基础的参数 信息.

UserProperties.java

package top.yueshushu.starter.mode;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import java.io.Serializable;
/**
 * @ClassName:User
 * @Description 自定义的一个实体
 * @Author zk_yjl
 * @Date 2021/10/22 16:57
 * @Version 1.0
 * @Since 1.0
 **/
/**
    不建议引用 @Data  lombok 第三方插件
 * @author yjl
 */
@SuppressWarnings("serial")
@ConfigurationProperties(prefix = "butterfly")
public class UserProperties implements Serializable {
    /**
      定义 final 常量,用于默认值
     */
    private final String DEFAULT_NAME="两个蝴蝶飞";
    private final Integer DEFAULT_AGE=26;
    private final String DEFAULT_DESCRIPTION="一个快乐的程序员";
    /**
        定义属性,使用默认值.
     */
    private String name=DEFAULT_NAME;
    private Integer age=DEFAULT_AGE;
    private String description=DEFAULT_DESCRIPTION;
    /**
       提示默认的构造方法
     */
    public UserProperties() {
    }
    public UserProperties(String name, Integer age, String description) {
        this.name = name;
        this.age = age;
        this.description = description;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", description='" + description + '\'' +
                '}';
    }
}

二.三 做什么, 要实现的功能

我们拿到用户的自定义参数 (没有的话,走默认的参数)后,要做实现事情,即要实现的功能.

UserPropertiesService.java

package top.yueshushu.starter.service;
import java.util.logging.Logger;
/**
 * @ClassName:UserService
 * @Description 用户提示的服务,表示有这一个类。
 * @Author zk_yjl
 * @Date 2021/10/22 17:02
 * @Version 1.0
 * @Since 1.0
 **/
public class UserPropertiesService {
   //定义日志
    Logger logger=Logger.getLogger(UserPropertiesService.class.getSimpleName());
    //参数信息,自定义starter 提供的全部的参数信息。
    private String name;
    private Integer age;
    private String description;
    public UserPropertiesService() {
    }
    // 接收参数
    public UserPropertiesService(String name,Integer age,String description) {
         this.name=name;
         this.age=age;
         this.description=description;
    }
    /**
     * 要实现的功能点, 这儿只做一个简单的打印。
     * @date 2021/10/29 14:30
     * @author zk_yjl
     * @param
     * @return void
     */
    public String println(){
        String message = String.format("大家好,我叫: %s, 今年 %s岁, 个人描述: %s",
                name, age,description);
        logger.info(">>>用户的信息:"+message);
        return message;
    }
}

二.四 动态热插拔配置

主要是将 这个 XxxService 管控起来。

UserPropertiesServiceConfiguration.java

package top.yueshushu.starter.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.yueshushu.starter.mode.UserProperties;
import top.yueshushu.starter.service.UserPropertiesService;
/**
 * @ClassName:UserServiceConfiguration
 * @Description 用户Service类的配置信息
 * @Author zk_yjl
 * @Date 2021/10/22 17:12
 * @Version 1.0
 * @Since 1.0
 **/
//表示是一个配置类
@Configuration
//用户输入的参数信息,可以放置到 UserProperties参数里面。一一对应起来
@EnableConfigurationProperties(UserProperties.class)
//存在某个条件类时触发, 即寻找到 UserPropertiesService.class时,才生效
@ConditionalOnClass(UserPropertiesService.class)
public class UserPropertiesServiceConfiguration {
    @Autowired
    private UserProperties userProperties;
    @Bean
    public UserPropertiesService userPropertiesService(){
        //注意,当条件触发时,才会创建 Bean 
        UserPropertiesService userService=new UserPropertiesService(
                userProperties.getName(),
                userProperties.getAge(),
                userProperties.getDescription()
        );
        return userService;
    }
}

二.五 配置,能被 SpringBoot 官方承认

必须要进行自动装配,否则这些东西,不被 SpringBoot 官方承认,那么在SpringBoot 项目里面进行引用,就找不到,造成功能不生效.

19.png

在 resources 目录下 创建 META-INF 目录,下面放置 spring.factories 文件 (必须叫这个名字)

# 添加配置信息,后面跟的是 自定义的那个configuration的全限定类名
org.springframework.boot.autoconfigure.EnableAutoConfiguration=top.yueshushu.starter.configuration.UserPropertiesServiceConfiguration  

现在,这个自定义配置的 ButterflyStarter 就算了成功了。

将其进行打包,安装到本地仓库 (老蝴蝶这儿是通过 mvn clean install 命令实现的)20.png

也可以通过 Lifecycle 生命周期按照进行实现

21.png

二.六 测试自定义 Starter

新创建一个 SpringBoot 的项目, StarterApply, 可以正常的启动和访问即可。

二.六.一 pom.xml 中添加依赖

除了 SpringBoot 该有的依赖外,导入刚才 install 生成的自定义Starter 依赖

 <!--添加我们自定义的依赖-->
        <dependency>
            <groupId>top.yueshushu</groupId>
            <artifactId>starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

二.六.二 测试自定义Starter

在 StarterApply 项目里面,添加 StarterTest 测试类,进行测试

package top.yueshushu.learn;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
import top.yueshushu.condition.Animal;
import top.yueshushu.condition.JavaAnimalConfig;
import top.yueshushu.starter.service.UserPropertiesService;
/**
 * @ClassName:StarterTest
 * @Description TODO
 * @Author zk_yjl
 * @Date 2021/10/22 17:26
 * @Version 1.0
 * @Since 1.0
 **/
@RunWith(SpringRunner.class)
@SpringBootTest
public class StarterTest {
    @Autowired
    private UserPropertiesService userPropertiesService;
    @Test
    public void starterPrintlnTest(){
        String message = userPropertiesService.println();
        System.out.println("Apply项目输出信息:"+message);
    }
}

二.六.二.一 进行测试

此时, application.yml 配置文件里面,没有关于自定义 Starter 的配置信息

进行测试,发现可以打印, 但是出现了乱码。 是 starter 本身出现的乱码。

22.png

二.六.二.二 解决 Starter 乱码问题

在 自定义的Starter pom.xml 添加编译插件,设置编码为 UTF-8

 <!--  spring boot 添加编辑方式-->
    <build>
        <plugins>
            <!-- 打包成可执行jar,防止中文乱码,必须要下面这一个插件  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

重新 mvn clean install ,然后刷新依赖即可。

23.png

解决了中文乱码的问题,

自定义 starter 里面的 日志信息会输出,同时项目里面的输出打印语言也生效。 输出的信息,是默认的信息

二.六.二.三 用户自定义参数测试

在 application.yml 中, 输入 butt 发现,有相应的属性提示

24.png

输入自定义的参数信息

butterfly:
  name: 岳泽霖
  age: 26
  description:  一个孤独的小孩子

进行测试

0.png

可以打印出用户自定义输入的参数信息。

说明 自定义 Starter 是生效的。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
7月前
32SpringBoot自定义Starter
32SpringBoot自定义Starter
39 0
32SpringBoot自定义Starter
|
3天前
|
设计模式 Java 机器人
SpringBoot3自动配置流程 SPI机制 核心注解 自定义starter
SpringBoot3自动配置流程 SPI机制 核心注解 自定义starter
|
12月前
|
架构师 NoSQL Java
【案例实战】SpringBoot3.x自定义封装starter实战
【案例实战】SpringBoot3.x自定义封装starter实战
【案例实战】SpringBoot3.x自定义封装starter实战
|
3天前
|
Java Spring 容器
SpringBoot2 | SpringBoot自定义AutoConfiguration | SpringBoot自定义starter(五)
SpringBoot2 | SpringBoot自定义AutoConfiguration | SpringBoot自定义starter(五)
23 0
|
3天前
|
Java Maven Spring
Spring Boot - 手把手教小师妹自定义Spring Boot Starter
Spring Boot - 手把手教小师妹自定义Spring Boot Starter
63 0
|
3天前
|
Java 数据库连接 Maven
SpringBoot【付诸实践 01】SpringBoot自定义starter保姆级教程(说明+源码+配置+测试)
SpringBoot【付诸实践 01】SpringBoot自定义starter保姆级教程(说明+源码+配置+测试)
38 1
|
3天前
|
运维 Java Maven
SpringBoot SPI 机制和实现自定义 starter
SpringBoot SPI 机制和实现自定义 starter
52 0
|
9月前
|
Java Maven Spring
Springboot自定义Starter启动器
Springboot自定义Starter启动器.md
134 0
Springboot自定义Starter启动器
|
9月前
|
Java Maven
springboot自定义starter启动器
springboot自定义starter启动器
58 0
|
10月前
|
NoSQL Java Redis
SpringBoot入门到精通-SpringBoot自定义starter(六)
SpringBoot入门到精通-SpringBoot自定义starter