[SpringBoot] 自定义spring-boot-starter
🍭介绍
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,这不应该是什么问题)。
🍡Starter自定义
springboot 官方建议springboot官方推出的starter 以spring-boot-starter-xxx的格式来命名,第三方开发者自定义的starter则以xxxx-spring-boot-starter的规则来命名,事实上,很多开发者在自定义starter的时候往往会忽略这个东西
自定义一个登录拦截的启动器,authority-spring-boot-starter
开发步骤:
新建工程
springboot版本自定义
没用的东西都删除
添加依赖(版本号会依赖parent,所以不需要指定)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> </dependency>
创建拦截器
authority/AuthorityInteceptor
package com.moming.authority; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; public class AuthorityInteceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception { String token = request.getParameter("token"); if(token == null || !token.equals("123")){ response.sendError(response.SC_UNAUTHORIZED); } return true; } }
创建属性绑定文件
authority/AuthorityProperties
package com.moming.authority; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; @Data @ConfigurationProperties(prefix = AuthorityProperties.AUTHORITY_PRE) public class AuthorityProperties { public final static String AUTHORITY_PRE="moming.authority"; /* 是否开启 */ private boolean enable ; /* 可以自定义配置拦截的路径 */ private String pathPatterns="/api/**"; /* 配置不拦截的路径 */ private String excludePathPatterns=""; }
注册拦截器
authority/WebConfig
package com.moming.authority; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Import; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Import(AuthorityProperties.class) @Order(Ordered.HIGHEST_PRECEDENCE) public class WebConfig implements WebMvcConfigurer { @Autowired private AuthorityProperties authorityProperties; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthorityInteceptor()) .addPathPatterns(authorityProperties.getPathPatterns()) .excludePathPatterns(authorityProperties.getExcludePathPatterns()); } }
创建自动配置类
authority/AuthorityAutoConfiguration
package com.moming.authority; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Import; @ConditionalOnProperty(prefix = AuthorityAutoConfiguration.AUTHORITY_PRE,value = "enable", havingValue = "true", matchIfMissing = false) @Import(WebConfig.class) public class AuthorityAutoConfiguration { public final static String AUTHORITY_PRE="moming.authority"; }
配置自动配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.moming.authority.AuthorityAutoConfiguration
最后打包成jar包,在我们的项目里面测试
🍬上传私仓
具体步骤参考:
上传成功
点击查看,父子依赖
<dependency> <groupId>com.moming</groupId> <artifactId>authority-spring-boot-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
🍦测试
新建一个测试项目进行测试
引入依赖
在application.properties配置文件中添加我们相应的配置
moming.authority.enable=true moming.authority.path-patterns=/api1/** moming.authority.exclude-path-patterns=/api2/**
测试接口
package com.moming.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @GetMapping("/api1/test1") public String test1(){ return "测试一"; } @GetMapping("/api2/test2") public String test2(){ return "测试二"; } }
预期效果拦截api1(需要token验证),api2不拦截
api2/test2测试成功
api1/test1,token为空或错误报401测试成功
api1/test1?token=123测试成功
🍨补充说明
Maven自动更新SNAPSHOT包
🧁使用spring-boot-configuration-processor生产配置元数据
引入Maven依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
Idea配置如下(非必需)
编译打包后,自动生成spring-configuration-metadata.json文件
其它App应用使用时,就可以有如下提示
🍹上传源码到私仓库
引入mvn依赖
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <configuration> <attach>true</attach> </configuration> <executions> <execution> <phase>compile</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
打包如下图
再执行deploy上传私仓
🍨总结
实现原理(SPI机制):
在META-INFO/spring.factories文件中配置接口的实现类名称,然后在程序中读取这些配置文件并实例化
主要的就是四个步骤
第一步:导入相关依赖
自动配置依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency>
配置处理器依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
第二步:新建自动化配置类
public class XXXXXXAutoConfiguration
导入业务或组件相关的Bean放入IOC容器
@Import(WebConfig.class)
@Bean public WebConfig webConfig(){ return new WebConfig(); }
第三步:配置相关的属性类
public class XXXXXXProperties{ /* 基本上都会有这个属性 */ private boolean enable; }
第四步:通过SPI机制把第二步的类放入IOC容器
resource/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.moming.authority.AuthorityAutoConfiguration
最后上传私仓,导入自定义starter的坐标依赖进行使用
因篇幅问题不能全部显示,请点此查看更多更全内容