spring boot大家都知道,是集成了spring的几乎所有类库,通过它核心的spring-boot-autoconfigure模块,结合一系列的starter来完成原本需要开发人员配置的各种xml和依赖jar的工作,开发人员针对自身需求,只要引入指定的starter即可。
下面就来实现一个自定义的spring boot starter。主要功能是拦截所有controller请求,并打印出请求参数和header部信息。
看了网上很多人都拆分成两个模块,autoconfigure模块和starter模块,我这里给的例子是只包含starter模块。
首先建一个maven项目
在resources目录下新建META-INF目录,并在此目录下新建spring.factories文件,内容如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.huang.AutoInitConfigurer,\
com.huang.CustomWebConfigurer
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\是固定的, 另外的是看需求,我这里定义了两个@Configuration
AutoInitConfigurer.java
@Configuration
public class AutoInitConfigurer {
@Bean
@ConditionalOnMissingBean
public LogInterceptor1 logInterceptor1() {
return new LogInterceptor1();
}
}
CustomWebConfigurer.java
@Configuration
public class CustomWebConfigurer extends WebMvcConfigurerAdapter {
private final LogInterceptor1 logInterceptor1;
@Autowired
public CustomWebConfigurer(LogInterceptor1 logInterceptor1) {
this.logInterceptor1 = logInterceptor1;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(logInterceptor1);
super.addInterceptors(registry);
}
}
定义拦截器,拦截所有controller的请求
@Slf4j
public class LogInterceptor1 extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String requestParams = getQueryString(request.getParameterMap());
String headers = getHeaderStr(request);
log.info("request params = {} header = {}", requestParams, headers);
return true;
}
public static String getHeaderStr(HttpServletRequest request) {
try {
StringBuilder sb = new StringBuilder(256);
Enumeration e = request.getHeaderNames();
while(e.hasMoreElements()) {
String name = (String)e.nextElement();
Enumeration headerValues = request.getHeaders(name);
while(headerValues.hasMoreElements()) {
sb.append(name).append("=").append((String)headerValues.nextElement()).append("&");
}
}
return sb.toString();
} catch (Exception e) {
return "";
}
}
public static String getQueryString(Map<String, String[]> params) {
try {
StringBuilder sb = new StringBuilder(256);
if (params != null && !params.isEmpty()) {
params.keySet().stream().forEach((key) -> sb.append(key).append("=").append(params.get(key)[0]).append("&"));
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
} catch (Exception e) {
return "";
}
}
}
pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.huang</groupId>
<artifactId>log-spring-boot-starter</artifactId>
<packaging>jar</packaging>
<version>1.0.0-SNAPSHOT</version>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.12.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*.yml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>*.yml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
最终打成jar包,上传到maven仓库。
好了,在我们的开发项目中只要依赖进来这个jar,并且定义一个WebMvcConfigurerAdapter类,并注册上面定义的LogInterceptor1 拦截器就能实现日志打印功能。
pom.xml依赖如下:
<dependency>
<groupId>com.huang</groupId>
<artifactId>log-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
定义CustomWebAppConfigurer类
@Configuration
@Slf4j
public class CustomWebAppConfigurer extends WebMvcConfigurerAdapter {
@Autowired
private LogInterceptor1 logInterceptor1;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(logInterceptor1).addPathPatterns("/**");
super.addInterceptors(registry);
}
}