SpringBoot自定义Starter
上篇文章简单记录了过滤器以及拦截器的使用,这篇文件结合SpringBoot
自定义starter
,以及拦截器
实现简单需求
需求:记录并打印的访问次数
1、为什么要自定义starter
在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定的包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一遍,麻烦至极。如果我们将这些可独立于业务代码之外的功配置模块封装成一个个starter,复用的时候只需要将其在pom中引用依赖即可,SpringBoot为我们完成自动装配。
2、自定义starter的命名规则
SpringBoot提供的starter以spring-boot-starter-xxx
的方式命名的。官方建议自定义的starter使用xxx-spring-boot-starter
命名规则。以区分SpringBoot生态提供的starter。
3、自定义starter
1、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>
<groupId>org.example</groupId>
<artifactId>ipCount-starter-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!--以SpringBoot 2.x 为开发版本。-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--以下两个包必须引入。-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
以SpringBoot 2.x 为开发版本。
2、自定义配置文件
配置文件自定义配置打印的格式,@ConfigurationProperties
和@Component
注解配置属性配置前缀和注入Spring容器。
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "tools.ip")
@Component
public class IpCountProperties {
private String display =DisplayModel.DISPLAY_SIMPLE.value;
//是否开始
private String isOpen;
public String getDisplay() {
return display;
}
public void setDisplay(String display) {
this.display = display;
}
public String getIsOpen() {
return isOpen;
}
public void setIsOpen(String isOpen) {
this.isOpen = isOpen;
}
public enum DisplayModel{
/**
* 显示模式
*/
DISPLAY_SIMPLE("simple"),
DISPLAY_DETAIL("Detail");
private String value;
public String getValue(){
return value;
}
public void setValue(String value){
this.value = value;
}
DisplayModel(String value){
this.value = value;
}
}
}
3、主要业务逻辑Service
自定义拦截器(即实现HandlerInterceptor重写preHandle等方法)
import com.example.qingxuan.config.IpCountProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;
public class IpCountInterceptor implements HandlerInterceptor {
@Autowired
private IpCountProperties ipCountProperties;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String remoteAddr = request.getRemoteAddr();
Object count = request.getSession().getAttribute("count");
if(Objects.isNull(count)){
count = 1L;
request.getSession().setAttribute("count",1);
} else {
count = (Integer) count + 1;
request.getSession().setAttribute("count",count);
}
if(IpCountProperties.DisplayModel.DISPLAY_DETAIL.getValue().equals(ipCountProperties.getDisplay())){ //detail模式
System.out.println("Myintercepor \n:" + remoteAddr + "count:\n" + count);
}else {
//simple模式
System.out.println("Myintercepor :" + remoteAddr + "count:" + count);
}
return true;
}
}
3、(重点)配置自动配置类,并加入到Spring IOC 容器
-
自定义配置类
建议的命名规则为XXAutoConfiguration
import com.example.qingxuan.service.IpCountInterceptor;
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;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableConfigurationProperties(IpCountProperties.class)
@ConditionalOnProperty(prefix = "tools.ip",name = "isOpen",havingValue = "true")
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("注册拦截器...");
registry.addInterceptor(ipCountInterceptor()).addPathPatterns("/intercepor/**");
}
//将自定义业务逻辑service注入ioc
@Bean
public IpCountInterceptor ipCountInterceptor(){
return new IpCountInterceptor();
}
}
▲@Configuration
标注为配置类:
▲@EnableConfigurationProperties
注解。该注解是用来开启对2步骤中 @ConfigurationProperties 注解配置Bean的支持。也就是@EnableConfigurationProperties注解告诉Spring Boot 能支持@ConfigurationProperties。
▲@ConditionalOnProperty
注解控制 该配置类是否生效。简单来说也就是我们可以通过在yml配置文件中配置
tools.ip.isOpen=true/false 控制配置类(即对应的功能)是否生效。
- 配置类注入IOC容器
SpringBoot 2.x:
在resource在新建META-INF目录并在该目录下创建spring.factories文件,在该文件中加入如下配置,该配置指定上步骤中定义的配置类为自动装配的配置(SpringBoot会扫描该文件中配置的全类名)。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.qingxuan.config.InterceptorConfig
其中org.springframework.boot.autoconfigure.EnableAutoConfiguration
这个key值不能更改,value值即为自定义配置类的全类名。
SpringBoot 3.x:
移除META-INF/spring.factories方式
只支持META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 增加自动配置
每行包含一个配置类全限定名。
使用maven打包到仓库,在需要引入的地方依赖使用
4、引入自定义starter
在需要使用的工程pom中引入
<groupId>org.example</groupId>
<artifactId>ipCount-starter-demo</artifactId>
<version>1.0-SNAPSHOT</version>
配置yml中,启用或关闭该功能
tools:
ip:
display: simple
isOpen: true //启用或关闭该功能,自定义的自动配置类中ConditionalOnProperty注解属性
5、测试
编写测试Controller
@RestController
public class MyController {
@GetMapping("/intercepor/test")
public String intercepor(){
return "hello,world and intercepor";
}
}
测试结果:
6、总结:
1、自定义业务逻辑service
2、自定义ConfigurationProperties配置类,并引入2个关键注解:@ConfigurationProperties
、@Component
3、自定义AutoConfiguration自动配置类, 并引入3个关键注解:@Configuration
、@EnableConfigurationProperties
、@ConditionalOnProperty
。并将第一步中的业务类使用@bean
注入IOC容器
4、在resource文件夹下创建META-INF/spring文件夹,在该文件夹中创建org.springframework.boot.autoconfigure.AutoConfiguration.imports为文件名,内容为自定义自动配置类的全类名,按行区分。在spring启动时扫描该文件,将文件内容中指定的自定义配置类实例化并注入到IOC容器中。
5、在需要使用的地方maven坐标引入,并在配置文件中配置指定的配置项。
7、结尾:
才疏学浅,仅作为个人学习笔记,如有侵权联系删除