【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第1张图片

欢迎来到我的CSDN主页!

我是君易--鑨,一个在CSDN分享笔记的博主。

推荐给大家我的博客专栏《SpringBoot开发》。

如果感觉还不错的话请给我关注加三连吧!


 前言

         在上一期的博客分享中和老铁们学习了有关Freemarker的相关知识,以及在SpringBoot中集成Freemarker运用,并且列举项目案例进行演示使用,已达到一个学以致用的效果。今天给大家带来的是自定义Starter在SpringBoot中的运用。

一、自定义Starter简介 

1. 概述(基本概念)

         在Spring Boot中,Starter是一种特殊的依赖,它可以帮助开发人员快速引入和配置某个特定的功能模块。

        Spring Boot的官方Starter并不一定包含所有开发人员所需的功能,这时候就需要自定义Starter来满足特定项目的需求。自定义Starter是一种自包含的、可重用的模块,它封装了一组特定功能的依赖和配置,并提供了简化配置的方式。通过自定义Starter,开发人员可以将一些常用的功能封装起来,使得在其他项目中引入这些功能变得更加简单和方便。

        SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。

 2. 为什么要使用它

        使用自定义Starter的优势及好处有以下几点:(如下表格所示)

自定义Starter的好处及优势
特点及优势 说明
模块化 自定义Starter可以将特定的功能模块化,使得开发人员可以更方便地管理和维护代码。
简化配置 通过自定义Starter,开发人员可以简化配置,减少重复的配置工作,提高开发效率。
提高代码重用性 自定义Starter可以封装一组特定功能的依赖和配置,使得在其他项目中引入这些功能变得更加简单和方便,从而提高代码重用性。
自定义功能 如果Spring Boot的官方Starter不能满足项目的需求,那么自定义Starter就可以发挥重要作用。开发人员可以根据项目需求自定义Starter,从而实现一些特定的功能。

         总之,在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定的包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一遍,麻烦至极。如果我们将这些可独立于业务代码之外的功能配置模块封装成一个个starter,复用的时候只需要将其在pom中引用依赖即可, SpringBoot为我们完成自动装配,简直不要太爽。

3. 应用场景

        在我们的日常开发工作中,可能会需要开发一个通用模块,以供其它工程复用。SpringBoot就为我们提供这样的功能机制,我们可以把我们的通用模块封装成一个个starter,这样其它工程复用的时候只需要在pom中引用依赖即可,由SpringBoot为我们完成自动装配。

常见的应用场景:

1)通用模块-短信发送模块

2)基于AOP技术实现日志切面

3)分布式雪花ID,Long转String,解决精度问题

4)微服务项目的数据库连接池配置

5)微服务项目的每个模块都要访问redis数据库,每个模块都要配置redisTemplat

4. 自动加载核心注解说明

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第2张图片

二、案例演示说明(模拟短信发送)

        我们先重新创建一个SpringBoot项目用于编写模拟短信发送。只选择lombok依赖即可。创建好项目之后,右侧点击Maven选择,点击项目,点击第一个文件夹,会显示一个install选项,点击该选项则项目存放到本地的Maven项目中。

        我们在本地的Maven仓库中可以查看到我们的下载的依赖。 路径时根据我们pom文件的版本来的。

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第3张图片 

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第4张图片

1. 命名规范说明

        Starter项目和SpringBoot工程结构没有什么区别,一样必须引入依赖的依赖如下


    org.springframework.boot
    spring-boot-configuration-processor
    true

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第5张图片

         不引用改以来无法在其他项目中引用自定义依赖。

 说明:spring-boot-configuration-processor 是一个注解处理器,用于处理 Spring Boot 配置类的注解,并生成配置属性的元数据。

 命名方式:

官方:

spring-boot-starter-{模块名}

自定义:

{模块名}-spring-boot-starter

 

2. 模拟短信发送

        如果创建好SpringBoot项目发现没有resources文件夹以及yml文件需要我们手动的去创建添加。

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第6张图片

         对yml文件进行对应编写

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第7张图片

         创建一个SmsProperties.java文件对其进行编写

SmsProperties.java 

package com.yx.starter;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * com.yx.starter
 *
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create 2023/12/14
 * 类似于短信发送的实体类
 */
@Data
@Component   //定义组件给Spring管理
public class SmsProperties {
//      从yml文件中获取到对应的值
    @Value("${sms.key}")
//    应用标识
    String key;
    @Value("${sms.secret}")
//    应用密钥
    String secret;



}

        在测试类中测试看看是否能够拿到yml文件中的值

测试类

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第8张图片

运行结果如下

         我们到此这一步并没有实现模拟发送短信的请求,因此我们要编写一个Service类以及它的实现类。

ISmsService.java

package com.yx.starter.service;

public interface ISmsService {

    /**
     * 发送短信
     *
     * @param phone        要发送的手机号
     * @param data         要发送的内容
     */
    void send(String phone, String data);

}

SmsServiceImpl.java 

package com.yx.starter.service;


import com.yx.starter.SmsProperties;
import org.springframework.stereotype.Service;

public class SmsServiceImpl implements ISmsService {

    private SmsProperties smsProperties; //null

    public SmsServiceImpl(SmsProperties smsProperties) {
        this.smsProperties=smsProperties;
    }

    @Override
    public void send(String phone, String data) {
        String key = smsProperties.getKey();
        String secret = smsProperties.getSecret();
        System.out.println("接入短信系统,Key=" + key + ",Secret=" + secret);
        System.out.println("短信发送,phone=" + phone + "data=" + data);
    }

}

        然后在测试类通过实例化实现类调用方法实现模拟短信发送 

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第9张图片

控制台输出的结果如下

         这里老铁们会有些疑惑,为什么没有使用@Service,因为我们要动态控制是否进行加载。通过yml文件中sms.enable的属性进行控制。所以我们要新建一个类来控制。

 SmsConfig.java

package com.yx.starter;

import com.yx.starter.service.ISmsService;
import com.yx.starter.service.SmsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * com.yx.starter
 *
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create 2023/12/14
 * 配置类
 * 动态控制是否使用短信发送
 * 这个类要Spring加载
 */
@Configuration   //表数配置类
public class SmsConfig {

//    控制Service是否加载到Spring中国
    @Autowired
    private SmsProperties smsProperties;

    @Bean//会在spring运行时自动执行,返回值会被放到spring容器中
    public ISmsService smsService(){
        return new SmsServiceImpl(smsProperties);
    }

}

        测试类对其进行调整运行

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第10张图片

         在之前编写SmsProperties使用了@Value不方便后续使用,该用@ConfigurationProperties在该类上适用

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第11张图片

        依次进行调试,控制台结果输出一样 

         我们可以将SmsProperties的@Component注释删除,在SmsConfig配置中使用@EnableConfigurationProperties指定指定的实体类。

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第12张图片

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第13张图片

调试结果一样

         接下来就是将它打包存放到本地的Maven仓库中,启动其他项目进行导入使用,在打包之前需要清空yml文件。

 导入短信依赖

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第14张图片

        导入了依赖之后我们在测试类中进行调试 ,还要配置其yml文件

 【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第15张图片

         配置完yml文件后,我们还需要编写短信发送的项目中的resources下新建META-INF文件夹,然后创建spring.factories文件; 在该文件中加入如下配置,该配置指定上步骤中定义的配置类为自动装配的配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.zking.scloudspringbootstarter.config.AutoConfig,\
  com.zking.scloudspringbootstarter.config.WebLogAutoConfig

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第16张图片

        我们对其项目进行修改,没修改都需要重新打包 ,下面是我的一些调整

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第17张图片

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第18张图片

        调试结果如下 

三、实现基于AOP技术的日志切面功能

准备工作

        重新创建一个项目,准备步骤与上面类似

 导入pom依赖


    org.springframework.boot
    spring-boot-configuration-processor
    true

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第19张图片

        一下是我的完整的pom依赖 

pom.xml 



    4.0.0
    com.yx
    Aspect
    0.0.1-SNAPSHOT
    Aspect
    Aspect
    
        1.8
        UTF-8
        UTF-8
        2.7.6
    

    

        
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        

        
            org.springframework
            spring-web
            5.3.10
        
        
            org.aspectj
            aspectjrt
            1.9.6
        
        
        
            org.springframework.boot
            spring-boot-configuration-processor
            true
        

        
            org.springframework.boot
            spring-boot-starter
        

        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            junit
            junit
        
    
    
        
            
                org.springframework.boot
                spring-boot-dependencies
                ${spring-boot.version}
                pom
                import
            
        
    

    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.8.1
                
                    1.8
                    1.8
                    UTF-8
                
            
            
                org.springframework.boot
                spring-boot-maven-plugin
                ${spring-boot.version}
                
                    com.yx.aspect.AspectApplication
                    true
                
                
                    
                        repackage
                        
                            repackage
                        
                    
                
            
        
    


1.  创建切面配置类Properties

WebLogProperties.java

package com.yx.aspect;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "yx.weblog")
public class WebLogProperties {
    private boolean enabled;

    public WebLogProperties() {
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}

2. 实现基于AOP技术的日志切面功能

WebLogAspect.java

package com.yx.aspect.config;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Aspect
@Component
@Slf4j
public class WebLogAspect {
    @Pointcut("execution(* *..*Controller.*(..))")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 记录下请求内容
        log.info("开始服务:{}", request.getRequestURL().toString());
        log.info("客户端IP :{}" , request.getRemoteAddr());
        log.info("参数值 :{}", Arrays.toString(joinPoint.getArgs()));
    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求,返回内容
        log.info("返回值 : {}" , ret);
    }

}

3. 创建自动配置类

WebLogConfig.java

package com.yx.aspect.config;

import com.yx.aspect.WebLogProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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;

/**
 * @ConditionalOnProperty
 * 配置属性a:
 * 1:不配置a        matchifmissing=false 不满足      matchifmissing=true 满足
 * 2:配置a=false    matchifmissing=false 不满足      matchifmissing=true 不满足
 * 3:配置a=true     matchifmissing=false 满足        matchifmissing=true 满足
 */
@Configuration
@EnableConfigurationProperties({WebLogProperties.class})
@ConditionalOnProperty(prefix = "yx.weblog",
        value = "enabled",matchIfMissing = true)
public class WebLogConfig {

    @Bean
    @ConditionalOnMissingBean
    public WebLogAspect webLogAspect(){
        return new WebLogAspect();
    }
}

4. 编写spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.yx.aspect.config.WebLogAspect,\
  com.yx.aspect.config.WebLogConfig

        路径仅供参考,实际路径根据自身的项目路径为主 

5. 打包安装

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第20张图片

6. 其他项目引用依赖

        导入对应的pom依赖以及配置yml文件

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第21张图片

        博主的配置仅供参考,具体的配置信息根据自身的项目信息进行配置 

 7. 启动项目进行检验

        启动项目并进行访问即可,然后在我们的IDEA控制台进行日志查看。


本期的博客分享到此结束

各位老铁慢慢消化

下期博客博主会带来新货

三连加关注,阅读不迷路 !

【SpringBoot】进阶之自定义starter(一起了解自定义starter的魅力)_第22张图片

你可能感兴趣的:(Spring,spring,boot,java,spring)