SpringBoot 手写 Starter

spring-boot-starter 模块

1.介绍

SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。

优点

一般认为,SpringBoot 微框架从两个主要层面影响 Spring 社区的开发者们:

  • 基于 Spring 框架的“约定优先于配置(COC)”理念以及最佳实践之路。

  • 提供了针对日常企业应用研发各种场景的 spring-boot-starter 自动配置依赖模块,如此多“开箱即用”的依赖模块,使得开发各种场景的 Spring 应用更加快速和高效。

​ SpringBoot 提供的这些“开箱即用”的依赖模块都约定以 spring-boot-starter- 作为命名的前缀,并且皆位于 org.springframework.boot 包或者命名空间下(虽然 SpringBoot 的官方参考文档中提到不建议大家使用 spring-boot-starter- 来命名自己写的类似的自动配置依赖模块,但实际上,配合不同的 groupId,这不应该是什么问题)。

2.starter自定义

springboot 官方建议springboot官方推出的starter 以spring-boot-starter-xxx的格式来命名,第三方开发者自定义的starter则以xxxx-spring-boot-starter的规则来命名,事实上,很多开发者在自定义starter的时候往往会忽略这个东西。

自定义一个分页:pagex-spring-boot-starter

开发步骤:

2.1新建工程

2.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.3.11.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <packaging>pom</packaging>
    <groupId>cn.jyx</groupId>
    <artifactId>win-root</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>8</java.version>
    </properties>
    <modules>
        <module>win-model</module>
        <module>win-core</module>
        <module>pagex-spring-boot-starter</module>
        <module>logtimex-spring-boot-starter</module>
    </modules>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.8.16</version>
            </dependency>
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.4.6</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

2.3model 模块

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>cn.jyx</groupId>
        <artifactId>win-root</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>win-model</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
 响应返回对象
package cn.win.model;

import lombok.Data;

@Data
public class ResponseDTO {
    private int code;
    private String msg;
    private Object data;
    public static ResponseDTO success(Object data)
    {
        ResponseDTO responseDTO = new ResponseDTO();
        responseDTO.setCode(0);
        responseDTO.setData(data);
        return responseDTO;
    }
    public static ResponseDTO error(int code,String msg)
    {
        ResponseDTO responseDTO = new ResponseDTO();
        responseDTO.setCode(code);
        responseDTO.setMsg(msg);
        return responseDTO;
    }
}

2.4core模块

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>cn.jyx</groupId>
        <artifactId>win-root</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>win-core</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
声明调用注解
package cn.win.core.annotations;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PageX {
}
package cn.win.core.exceptioin;

public class BizException extends RuntimeException {
    private int code;
    private String msg;

    public int getCode() {
        return code;
    }

    public BizException(int code, String msg) {
        super();
        this.code = code;
        this.msg = msg;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

pagex-spring-boot-starter 模块

<?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>cn.jyx</groupId>
        <artifactId>win-root</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>pagex-spring-boot-starter</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>

        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.jyx</groupId>
            <artifactId>win-core</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>cn.jyx</groupId>
            <artifactId>win-model</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>




</project>
全局响应处理类 advice

用于处理Spring MVC框架中的异常和响应体的转换

package cn.win.logtimex.advice;

import cn.hutool.json.JSONUtil;
import cn.win.core.exceptioin.BizException;
import cn.win.model.ResponseDTO;
import com.github.pagehelper.Page;

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.HashMap;

@RestControllerAdvice
public class MyResponseAdvice implements ResponseBodyAdvice {

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        return true;
    }

    @ExceptionHandler(Exception.class)
    public Object exceptionHandler(Exception ex){
        ex.printStackTrace();
        if(ex instanceof BizException){
            BizException bizException= (BizException) ex;
            return ResponseDTO.error(bizException.getCode(),bizException.getMsg());
        }
        return ResponseDTO.error(500, ex.getMessage());
    }
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if (body instanceof ResponseDTO){
            return body;
        }
        ResponseDTO dto = ResponseDTO.success(body);
        if(body instanceof Page){
            Page page = (Page) body;
            long total = page.getTotal();
            HashMap<String,Object> map = new HashMap<>();
            map.put("total",total);
            map.put("items",body);
            dto = ResponseDTO.success(map);
        }
        if(aClass == StringHttpMessageConverter.class){
            return JSONUtil.toJsonStr(dto);
        }
       return dto;
    }
}
AOP
package cn.win.logtimex.aop;


import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Component
@Aspect
public class PagexAop {
    //切点表达式,表示该切面将应用于所有被PageX注解标记的方法。
    @Pointcut("@annotation(cn.win.core.annotations.PageX)")
    public void point(){}
    @Around("point()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("执行方法之前");
        RequestAttributes requestAttributes= RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        String pageNum = request.getParameter("pageNum");
        String pageSize = request.getParameter("pageSize");
        if (ObjectUtil.isNotEmpty(pageNum)&&ObjectUtil.isNotEmpty(pageSize)){
            PageHelper.startPage(Integer.parseInt(pageNum),Integer.parseInt(pageSize));
        }
        Object result = pjp.proceed(); // 调用目标方法
        System.out.println("执行方法之后");
        return result;
    }
}

创建自动配置类AuthorityAutoConfigruation  

package cn.win.logtimex.autoconfiguration;

import cn.win.logtimex.advice.MyResponseAdvice;
import cn.win.logtimex.aop.PagexAop;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import( {PagexAop.class, MyResponseAdvice.class})
// cn.smart.pagex.enbale = xxx
@ConditionalOnProperty(prefix = "cn.win.pagex", value = "enable",havingValue="true",matchIfMissing=true)
public class PageXAutoConfiguration { // 领头羊
}
配置类
package cn.win.logtimex.properties;

import lombok.Data;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "cn.win.pagex")
@EnableAutoConfiguration
public class PageXProperties {
    private boolean enable=true;
}
配置自动配置

在resourecs文件目录下创建META-INF,并创建我们自己的spring.factories,并把我们的 MemberStaterAutoConfiguration 添加进去

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  cn.win.logtimex.autoconfiguration.PageXAutoConfiguration

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/418463.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

果园预售系统|基于Springboot的果园预售系统设计与实现(源码+数据库+文档)

果园预售系统目录 目录 基于Springboot的果园预售系统设计与实现 一、前言 二、系统功能设计 三、系统功能设计 1 、果园管理 2、水果管理 3、果树管理 4、公告管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获…

C++ 原子变量

概述 C中原子变量&#xff08;atomic&#xff09;是一种多线程编程同步机制&#xff0c;它能够确保对共享变量的操作在执行时不会被其他线程的操作干扰&#xff0c;atomic是提供一种生成原子操作数的一种机制&#xff0c;避免竞态条件(race condition)和死锁(deadlock)等问题。…

css5定位

css 一.定位1.概念&#xff08;定位定位模式边位移&#xff09;2.静态位移static&#xff08;不常用&#xff09;3.相对定位relative&#xff08;不脱标&#xff09;&#xff08;占位置&#xff09;4.绝对定位absolute&#xff08;脱标&#xff09;&#xff08;不占位置&#x…

『Linux从入门到精通』第 ㉒ 期 - 动静态库

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f427;什么是库&#xff1f;&#x1f427;为什么要有库&#xff1f;&#x1f427;写一个自己的库&#x1f426;方法一&#x1f426;方法二 静态库&#x1f426;标准化&#x1f426;方法三 动态库&#x1f426;配置动…

Python根据3个点确定两个向量之间的夹角-180度到180方向进行矫正

import cv2 import numpy as np # 读取图片 image cv2.imread(rD:\dmp\cat.jpg) height, width image.shape[:2] # 定义三个定位点&#xff08;这里假设是图片上的坐标&#xff09;&#xff0c;分别表示原点&#xff0c;向量1终点&#xff0c;向量2终点&#xff0c;下…

动画原理:表面形变算法的思考与总结

前言&#xff1a; 之前我的文章 Mesh形变算法_mesh算法-CSDN博客就有大致的讨论过&#xff0c;介绍的也比较粗略&#xff01;现在主要是想在Triangulated Surface Mesh Deformation方向上更深入的讨论一下&#xff01;结合今年我对这一块的学习谈谈我的理解~ 下面要介绍大致几…

学校机房Dev c++解决中文乱码问题

工具->编译选项->勾选 编译时加入以下命令 -fexec-charsetGBK -finput-charsetUTF-8 显示中文&#xff1a;工具->编辑器选项->去掉第一个的勾勾。

WebFlux的探索与实战 - r2dbc的分页查询

自从上次立下这系列的FLAG之后就再也不想碰了。今天难得早起出门面试&#xff0c;回家之后突发奇想打算再写点儿什么敷衍一下&#xff0c;于是便有了这篇文章。 前言 虽然响应式API更加适合流式列表的查询&#xff0c;但是分页这东西可是很常见的。 也没什么前言可说&#xf…

opencv中的rgb转gray的计算方法

转换原理 在opencv中&#xff0c;可以使用cv2.cvtColor函数将rgb图像转换为gray图像。示例代码如下&#xff0c; import cv2img_path "image.jpg" image cv2.imread(img_path) gray_image cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) mean gray_image.mean() pri…

在实训云平台上配置云主机

文章目录 零、学习目标一、实训云升级二、实训云登录&#xff08;一&#xff09;登录实训云&#xff08;二&#xff09;切换界面语言&#xff08;三&#xff09;规划云主机实例 三、创建网络三、创建路由器2024-2-29更新到此四、添加接口五、创建端口六、添加安全组规则七、创建…

公网IP怎么获取?

公网IP是网络中设备的唯一标识符&#xff0c;用于在Internet上进行通信和定位。对于普通用户来说&#xff0c;了解如何获取自己的公网IP是很有必要的&#xff0c;本文将介绍几种获取公网IP的方法。 方法一&#xff1a;通过路由器查询 大多数家庭和办公室使用的路由器都会有一个…

生成式AI设计模式:综合指南

原文地址&#xff1a;Generative AI Design Patterns: A Comprehensive Guide 使用大型语言模型 (LLM) 的参考架构模式和心理模型 2024 年 2 月 14 日 对人工智能模式的需求 我们在构建新事物时&#xff0c;都会依赖一些经过验证的方法、途径和模式。对于软件工程师来说&am…

Maven【3】( 依赖的范围,传递性和依赖的排除)(命令行操作)

文章目录 【1】依赖的范围结论验证①验证 compile 范围对 main 目录有效②验证test范围对main目录无效③验证test和provided范围不参与服务器部署 【2】依赖的传递性①compile 范围&#xff1a;可以传递②test 或 provided 范围&#xff1a;不能传递 【3】依赖的排除 【1】依赖…

apollo cyber RT初学

一 初识 ROS无法调度协调&#xff0c;且通信开销大&#xff0c;耗资源。百度自动驾驶团队开发了Cyber RT。 CyberRT从下到上依次为&#xff1a; 基础库&#xff1a;高性能&#xff0c;无锁队列&#xff1b; 通信层&#xff1a;Publish/Subscribe机制&#xff0c;Service/Cli…

h5移动端开发,android常见面试题及答案

1、Android系统的架构 Android系统架构之应用程序 Android会同一系列核心应用程序包一起发布&#xff0c;该应用程序包包括email客户端&#xff0c;SMS短消息程序&#xff0c;日历&#xff0c;地图&#xff0c;浏览器&#xff0c;联系人管理程序等。所有的应用程序都是使用JAV…

【进阶C语言】内存函数(详解)

前言 上一期讲的函数都是和字符串相关的&#xff0c;但是我们在操作数据的时候&#xff0c;不仅仅是操作字符串的数据&#xff0c;还得需要内存函数的应用 内存函数的应用 1. memcpy1.1 memcpy的介绍1.2 memcpy的使用1.3 模拟实现memcpy库函数1.4 我想在1&#xff0c;2后面打印…

day05_用户管理minIO角色分配(页面制作,查询用户,添加用户,修改用户,删除用户,用户头像,查询所有角色,保存角色数据)

文章目录 1 用户管理1.1 页面制作1.2 查询用户1.2.1 需求说明1.2.2 后端接口需求分析SysUserSysUserDtoSysUserControllerSysUserServiceSysUserMapperSysUserMapper.xml 1.2.3 前端对接实现思路sysUser.jssysRole.vue 1.3 添加用户1.3.1 需求说明1.3.2 页面制作1.3.3 后端接口…

C语言题目:指针

1. 下面代码的结果是&#xff1a; #include <stdio.h> int i; int main() {i--;if (i > sizeof(i)){printf(">\n");}else{printf("<\n");}return 0; }答案&#xff1a;> 解析&#xff1a; i作为全局变量且在未赋值的情况下初始值为1&…

每日一练:LeeCode-701、二叉搜索树中的插入操作【二叉搜索树+DFS+全搜】

本文是力扣 每日一练&#xff1a;LeeCode-701、二叉搜索树中的插入操作【二叉搜索树DFS全搜】学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 …

看视频,学习使用MindOpt APL 建模语言编码数学规划问题,练习语法,实战拿奖品

活动介绍 活动名称&#xff1a;看视频&#xff0c;补充代码&#xff0c;拿精美礼品 活动规则&#xff1a; 浏览视频学习MAPL&#xff0c;完善“例题”。需要完善的内容&#xff1a;补充约束条件、读取csv表格数据&#xff0c;将决策变量的取值输出为csv表格&#xff0c;验证一…