Spring Boot 手写starter!!!

原因:为什么要手写starter???

原因:简化功能。

实例:以分页为例:写一个starter。

1.首先定义一个PageX注解。

java 复制代码
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PageX {
}

2.对这个注解进行增强,PageXAop。

java 复制代码
/*
 * Copyright (c) 2020, 2024,  All rights reserved.
 *
 */
package cn.scl.pagex.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;

/**
 * <p>Project: pages - PageXAOP</p>
 * <p>Powered by scl On 2024-02-18 16:32:09</p>
 * <p>描述:<p>
 *
 * @author 孙臣龙 [1846080280@qq.com]
 * @version 1.0
 * @since 17
 */
@Component
@Aspect
public class PageXAOP {

    @Pointcut("@annotation(cn.scl.core.annotations.PageX)")
    public void pointcut(){}

    @Around("pointcut()")
    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;
    }
}

3、定义统一返回格式,ResponseDTO。

java 复制代码
/*
 * Copyright (c) 2020, 2024,  All rights reserved.
 *
 */
package cn.scl.model.dto;

import lombok.Data;

/**
 * <p>Project: pages - ResponseDTO</p>
 * <p>Powered by scl On 2024-02-18 16:26:38</p>
 * <p>描述:<p>
 *
 * @author 孙臣龙 [1846080280@qq.com]
 * @version 1.0
 * @since 17
 */
@Data
public class ResponseDTO {
    private int code ; //0为请求成功,非0为请求失败
    private String message; //返回的信息
    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 message){
        ResponseDTO responseDTO = new ResponseDTO();
        responseDTO.setCode(code);
        responseDTO.setMessage(message);
        return responseDTO;
    }
}

4、统一对controller进行处理,MyResponseAdvice。

java 复制代码
/*
 * Copyright (c) 2020, 2024,  All rights reserved.
 *
 */
package cn.scl.pagex.advice;

import cn.hutool.json.JSONUtil;
import cn.scl.core.exception.BizException;
import cn.scl.model.dto.ResponseDTO;
import com.github.pagehelper.Page;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
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;
import java.util.Map;

/**
 * <p>Project: pages - MyResponseAdvice</p>
 * <p>Powered by scl On 2024-02-18 16:48:23</p>
 * <p>描述:<p>
 *
 * @author 孙臣龙 [1846080280@qq.com]
 * @version 1.0
 * @since 17
 */
@RestControllerAdvice
public class MyResponseAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }


    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if (body instanceof ResponseDTO){
            return body;
        }
        if (aClass == StringHttpMessageConverter.class){
            return JSONUtil.toJsonStr(body);
        }
        ResponseDTO dto = ResponseDTO.success(body);
        if (body instanceof Page) {
            Page page = (Page) body;
            long total = page.getTotal();
            Map<String, Object> m = new HashMap<>();
            m.put("total", total);
            m.put("item", body);
            dto = ResponseDTO.success(m);
        }
        return dto;
    }
}

5、定义一个属性类,用来是否开启注解,PageXProperties。

java 复制代码
/*
 * Copyright (c) 2020, 2024,  All rights reserved.
 *
 */
package cn.scl.pagex.properties;

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

/**
 * <p>Project: scl-root - PageXProperties</p>
 * <p>Powered by scl On 2024-02-19 16:59:30</p>
 * <p>描述:<p>
 *
 * @author 孙臣龙 [1846080280@qq.com]
 * @version 1.0
 * @since 17
 */
@Data
@ConfigurationProperties(prefix = "cn.scl.pagex")
@EnableAutoConfiguration
public class PageXProperties {
   private boolean enable=true;
}

6、将需要装配配的类集中起来,自动装配时只需扫描这一个类即可,PageXAutoConfiguration。

java 复制代码
@Configuration
@Import({MyResponseAdvice.class, PageXAOP.class})
@ConditionalOnProperty(prefix = "cn.scl.pagex" ,value = "enable" ,havingValue = "true",matchIfMissing = true)
public class PageXAutoConfiguration { //领头羊
}

7、开启自动装配,在resource目录下新建,META-INF/spring.factories文件。

java 复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  cn.scl.pagex.autoconfiguration.PageXAutoConfiguration

8.如何打包发布??
目的:可以把我们书写的jar包发布到maven私有仓库,简称私仓

1. 打开云效

2.点击 非生产库-snapshot

mave release仓库与snapshot仓库区别?

在软件开发中,"Maven release 仓库"和"Maven snapshot 仓库"是两种不同的仓库类型,用于存储Maven构建的软件包。

Maven Release 仓库:

Maven Release 仓库用于存储稳定版本的软件包,这些版本经过测试并且在生产环境中使用。当项目开发到一个稳定的版本时,开发人员可以创建一个发布版本并将其上传到 Maven Release 仓库。这些版本具有固定的版本号,并且不会被覆盖或修改。开发人员和其他用户可以通过指定这些稳定的版本号来下载和使用软件包,以确保他们获取的是稳定且经过验证的代码。

Maven Snapshot 仓库:

Maven Snapshot 仓库用于存储开发中的版本或快照版本的软件包。这些版本在开发过程中可能经常变化,并且不稳定。开发人员可以将项目的最新代码以快照版本的形式部署到 Maven Snapshot 仓库中。快照版本具有动态的版本号,通常带有时间戳或其他唯一标识符,以区别于稳定版本。快照版本可以方便地进行测试和共享,但不适合在生产环境中使用,因为它们可能包含未解决的问题或经过充分验证的代码。

这两种仓库的区别在于稳定版本和开发版本之间的区别,以及用途和用例。 Maven Release 仓库用于存储稳定版本,而 Maven Snapshot 仓库则用于存储开发中的快照版本。

3.根据如下步骤,下载setting.xml文件

4.将下载文件放置到 C:\Users\你的用户名\.m2 如下位置,如果你之前有settings.xml文件,请先提前备份.

5. 双击 deploy 就可以发布到私仓,

在私仓就可以看到了对应的jar包,别人就可以直接使用了。

6.如果要想把源码也打包进去,需要maven-source-plugin插件

复制代码
 <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>

XML

再次打包,你会看到私仓多出-source.jar , 别人在使用的时候,可以下载源码查看

目录结构:

相关推荐
喵手7 分钟前
如何利用Java的Stream API提高代码的简洁度和效率?
java·后端·java ee
-Xie-9 分钟前
Maven(二)
java·开发语言·maven
IT利刃出鞘21 分钟前
Java线程的6种状态和JVM状态打印
java·开发语言·jvm
薛晓刚25 分钟前
当MySQL的int不够用了
数据库
SelectDB技术团队1 小时前
Apache Doris 在菜鸟的大规模湖仓业务场景落地实践
数据库·数据仓库·数据分析·apache doris·菜鸟技术
星空下的曙光1 小时前
mysql 命令语法操作篇 数据库约束有哪些 怎么使用
数据库·mysql
小楓12011 小时前
MySQL數據庫開發教學(一) 基本架構
数据库·后端·mysql
天天摸鱼的java工程师1 小时前
Java 解析 JSON 文件:八年老开发的实战总结(从业务到代码)
java·后端·面试
白仑色1 小时前
Spring Boot 全局异常处理
java·spring boot·后端·全局异常处理·统一返回格式
染落林间色1 小时前
达梦数据库-实时主备集群部署详解(附图文)手工搭建一主一备数据守护集群DW
数据库·sql