一.创建自定义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 https://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.7.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>mystarter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mystarter</name>
<description>mystarter</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin><!--编译跳过测试文件检查的生命周期-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.创建一个统计IP访问次数的服务方法
/**
* @author qinxun
* @date 2023-04-26
* @Descripion: ip访问次数的服务层
*/
public class IpCountService {
// 创建一个map集合
private final Map<String, Integer> ipCountMap = new ConcurrentHashMap<>();
@Autowired
private HttpServletRequest httpServletRequest;
/**
* 每次调用当前操作,就记录当前访问的IP,然后累加访问次数
*/
public void count() {
// 1.获取当前操作的IP地址
String ip = httpServletRequest.getRemoteAddr();
// 2.根据IP地址从Map取值,并递增次数
ipCountMap.put(ip, ipCountMap.getOrDefault(ip, 0) + 1);
System.out.println(ipCountMap);
}
}
3.定义自动配置类
/**
* @author qinxun
* @date 2023-04-26
* @Descripion: 定义自动配置类
*/
public class IpAutoConfiguration {
@Bean
public IpCountService ipCountService(){
return new IpCountService();
}
}
4.加载自动配置类
5.maven install安装到本地
这样就创建了一个starter.
2.在其他项目进行测试
pom文件引入刚才创建的自定义依赖
<!--引入自定义starter-->
<dependency>
<groupId>com.example</groupId>
<artifactId>mystarter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
在控制层调用测试方法
/**
* @author qinxun
* @date 2023-04-26
* @Descripion: 测试
*/
@RestController
public class TestController {
@Resource
private IpCountService ipCountService;
@GetMapping("/testIp")
public void testIp(){
ipCountService.count();
System.out.println("方法触发成功");
}
}
浏览器访问 http://localhost:8081/testIp
{0:0:0:0:0:0:0:1=1}
方法触发成功
{0:0:0:0:0:0:0:1=2}
方法触发成功
3.通过yml设置功能参数
tools:
ip:
cycle: 10 #定时周期
cycleReset: true #是否周期定时清理
model: "simple" #日志模式
我们预设置3个属性,分别用来控制日志显示周期(cycle),周期数据是否清空(cycleReset),数据显示格式(model)
3.1定义封装参数的属性类,读取配置参数
import com.example.mystarter.enums.LogEnum;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author qinxun
* @date 2023-04-27
* @Descripion:
*/
@ConfigurationProperties(prefix = "tools.ip")
public class IpProperties {
/**
* 日志显示周期
*/
private Long cycle = 5L;
/**
* 是否周期内重置数据
*/
private Boolean cycleReset = false;
/**
* 日志输出模式 detail:详细模式 simple:简单模式
*/
private String model = LogEnum.DETAIL.getValue();
public Long getCycle() {
return cycle;
}
public Boolean getCycleReset() {
return cycleReset;
}
public String getModel() {
return model;
}
public void setCycle(Long cycle) {
this.cycle = cycle;
}
public void setCycleReset(Boolean cycleReset) {
this.cycleReset = cycleReset;
}
public void setModel(String model) {
this.model = model;
}
}
/**
* @author qinxun
* @date 2023-04-27
* @Descripion: 日志枚举
*/
public enum LogEnum {
DETAIL("detail"),
SIMPLE("simple");
private String value;
LogEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
3.2加载属性类
/**
* @author qinxun
* @date 2023-04-26
* @Descripion: 定义自动配置类
*/
@EnableScheduling
@EnableConfigurationProperties(IpProperties.class)
public class IpAutoConfiguration {
@Bean
public IpCountService ipCountService(){
return new IpCountService();
}
}
3.3自定义starter中的业务功能调整
/**
* @author qinxun
* @date 2023-04-26
* @Descripion: ip访问次数的服务层
*/
public class IpCountService {
// 创建一个map集合
private final Map<String, Integer> ipCountMap = new ConcurrentHashMap<>();
@Autowired
private HttpServletRequest httpServletRequest;
@Autowired
private IpProperties ipProperties;
/**
* 每次调用当前操作,就记录当前访问的IP,然后累加访问次数
*/
public void count() {
// 1.获取当前操作的IP地址
String ip = httpServletRequest.getRemoteAddr();
// 2.根据IP地址从Map取值,并递增次数
ipCountMap.put(ip, ipCountMap.getOrDefault(ip, 0) + 1);
}
@Scheduled(cron = "0/5 * * * * ?")
public void print() {
// 详细模式日志展示格式
if (ipProperties.getModel().equals(LogEnum.DETAIL.getValue())) {
for (Map.Entry<String, Integer> entry : ipCountMap.entrySet()) {
System.out.printf("ip:[%s],nums:[%d]%n", entry.getKey(), entry.getValue());
}
}
// 简洁模式日志展示格式
else if (ipProperties.getModel().equals(LogEnum.SIMPLE.getValue())) {
for (String key : ipCountMap.keySet()) {
System.out.printf("ip:[%s]%n", key);
}
}
// 阶段内统计数据是否清除
if (ipProperties.getCycleReset()) {
ipCountMap.clear();
System.out.println("清空map数据");
}
}
}
完成对自定义starter项目的修改,就先用maven clean一下项目再install到本地。
3.4浏览器测试 http://localhost:8081/testIp
2023-04-27 09:18:57.155 INFO 14416 --- [nio-8081-exec-1] o.apache.tomcat.util.http.parser.Cookie : A cookie header was received [This is username=admin;] that contained an invalid cookie. That cookie will be ignored.
Note: further occurrences of this error will be logged at DEBUG level.
2023-04-27 09:18:57.158 INFO 14416 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-04-27 09:18:57.158 INFO 14416 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-04-27 09:18:57.159 INFO 14416 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
方法触发成功
ip:[0:0:0:0:0:0:0:1]
清空map数据
我们当前使用的配置是使用简单模式日志和定期清理的模式
tools:
ip:
cycle: 10 #定时周期
cycleReset: true #周期定时清理
model: "simple" #日志模式
日志显示定期清理了集合中的内容和使用简单模式日志的输出。