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 {@Overridepublic 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());}@Overridepublic 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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

配置之道:深入研究Netty中的Option选项

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 配置之道&#xff1a;深入研究Netty中的Option选项 前言Option的基础概念ChannelOption与Bootstrap Option常见的ChannelOption类型ChannelConfig的使用Option的生命周期不同传输协议的Option 前言 在…

kotlin开发框架,50家大厂面试万字精华总结

与其它行业一样&#xff0c;凡是有高级和普通&#xff0c;虽然都是敲代码但也有大牛和普通之分&#xff0c;大牛程序员&#xff0c;一个人比一个团队做项目都做得快&#xff0c;**最为出名的当属十几年前求伯君在做wps时&#xff0c;一个人完成了微软二十人团队没有完成的项目需…

并查集基础,死去的回忆突然攻击我

并查集普及【模板】并查集 - 洛谷 #include<iostream> #include<cstring> #include<queue> #include<vector> #include<algorithm> using namespace std; #define int long long typedef pair<int,int> PII; #define xx first #define y…

种花

分情况&#xff1a; 第一盆k种选择&#xff0c;之后全部k-1种选择 每次相乘结果对1e97取模 #include <iostream> #include <vector> #include <algorithm> using namespace std; #define endl \n const int N 1e9 7;int main() {ios::sync_with_stdio(f…

简评ORACLE/MYSQL/PG的逻辑复制

postgresql逻辑复制 ​​​​ &#xff08;https://www.pgconf.asia/JA/2017/wp-content/uploads/sites/2/2017/12/D2-A7-EN.pdf&#xff09; PostgreSQL把所有逻辑解析相关的事情全部放在数据库中的复制槽进行管理&#xff0c;大包大揽。早期版本的逻辑复制支持的还不太好&a…

ICML23 - Synthetic Data for Model Selection

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 本文关注的问题为&#xff1a;是否可以使用合成数据&#xff08;Synthetic Data&#xff09;用于模型选择&#xff1f;即不…

LeetCode383. 赎金信(C++)

LeetCode383. 赎金信 题目链接代码 题目链接 https://leetcode.cn/problems/ransom-note/description/ 代码 class Solution { public:bool canConstruct(string ransomNote, string magazine) {int record[26] {0};if(ransomNote.size() > magazine.size()) return fa…

浅析扩散模型与图像生成【应用篇】(四)——Palette

4. Palette: Image-to-Image Diffusion Models 该文提出一种基于扩散模型的通用图像转换&#xff08;Image-to-Image Translation&#xff09;模型——Palette&#xff0c;可用于图像着色&#xff0c;图像修复&#xff0c;图像补全和JPEG图像恢复等多种转换任务。Palette是一种…

【Web自动化测试——代码篇十二】自动化测试模型——数据驱动测试和关键字驱动测试

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

基于springboot+vue的可盈保险合同管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

python实现常见一元随机变量的概率分布

一. 随机变量 随机变量是一个从样本空间 Ω \Omega Ω到实数空间 R R R的函数&#xff0c;比如随机变量 X X X可以表示投骰子的点数。随机变量一般可以分为两类&#xff1a; 离散型随机变量&#xff1a;随机变量的取值为有限个。连续型随机变量&#xff1a;随机变量的取值是连…

vue-router4 (六) 路由嵌套

应用场景&#xff1a; ①比如京东页面的首页、购物车、我的按钮&#xff0c;可以点击切换到对应的页面&#xff1b; ② 比如 Ant Design左侧这些按钮点击就会切到对应的页面&#xff0c;此时可以把左侧按钮放在父路由中&#xff0c;右侧的子路由 1.路由配置&#xff0c;子路由…