目录
自定义starter
统计独立IP访问次数
使用自定义starter
设置拦截器
开启yml提示功能
需求分析:
1、数据记录位置:Map/Redis
2|功能触发位置:每次web请求(拦截器)
3、业务参数(配置项)
创建一个模块
pom.xml中
4.0.0
com.kc
springboot_ipcount_starter
0.0.1-SNAPSHOT
1.8
UTF-8
UTF-8
2.4.1
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-dependencies
${spring-boot.version}
pom
import
写入主要的类
package com.kc.service;
import com.kc.properties.IpProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
public class IpCountService {
private HashMap ipCountMap=new HashMap<>();
//当前的request对象的注入工作由使用当前starter的工程提供自动装配
@Autowired
private HttpServletRequest httpServletRequest;
public void count(){
//每次调用当前操作,就记录当前访问的IP,然后累加访问次数
//1、获取当前操作的ip地址
String ip=httpServletRequest.getRemoteAddr();
//2、根据ip地址从Map取值,并递增
Integer value = ipCountMap.get(ip);
//判断当前ip否存在
if(value==null){
ipCountMap.put(ip, 1);
}else {
ipCountMap.put(ip, value+1);
}
}
//注入配置类
@Autowired
private IpProperties ipProperties;
//打印
@Scheduled(cron = "0/2 * * * * ?") //2秒执行一次
public void show(){
System.out.println(" IP访问监控 ");
if (ipProperties.getModel().equals(IpProperties.LogModel.DETAIL.getValue())) {
System.out.println("+-----ip-address-----+--num--+");
//同时获取key和value
for (Map.Entry entry : ipCountMap.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
//format格式输出,%18s是给字符串占18位和%5d是给数字占5位符
System.out.println(String.format("|%18s |%5d |", key,value));
}
System.out.println("+--------------------+-------+");
}else if (ipProperties.getModel().equals(IpProperties.LogModel.SIMPLE.getValue())){
System.out.println("+-----ip-address-----+");
//同时获取key和value
for (String key : ipCountMap.keySet()) {
System.out.println(String.format("|%18s |", key));
}
System.out.println("+--------------------+-------+");
}
//是否清除数据
if (ipProperties.getCycleReset()){
ipCountMap.clear();
}
}
}
配置类下
package com.kc.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "ip")
public class IpProperties {
/**
* 日志显示周期
*/
private long cycle=5L;
/**
* 是否重置周期数据
*/
private boolean cycleReset=false;
/**
* 日志输出模式 detail :详细模式 simple 极简模式
*/
private String model=LogModel.DETAIL.value;
/**
* 使用枚举来存储
*/
public enum LogModel{
DETAIL("detail"),
SIMPLE("simple");
private String value;
LogModel(String value) {
this.value=value;
}
public String getValue() {
return value;
}
}
public boolean getCycleReset() {
return cycleReset;
}
public void setCycleReset(boolean cycleReset) {
this.cycleReset = cycleReset;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
自动配置信息类
package com.kc.autoConfig;
import com.kc.service.IpCountService;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling//开启定义任务调度
@Import(IpCountService.class)
public class IpAutoConfiguration {
}
在资源中新建
META-INF下的spring.factories
#要自动配置的类写在这
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.kc.autoConfig.IpAutoConfiguration
这个自定义starter就完成了
导入对应的坐标即可
注入和使用对应的方法
package com.kc.interceptor;
import com.kc.service.IpCountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class IpCountInterceptor implements HandlerInterceptor {
@Autowired
private IpCountService ipCountService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
ipCountService.count();
ipCountService.show();
return true;
}
}
为了能被springmvc识别还得写个配置
package com.kc.interceptor;
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(proxyBeanMethods = true)//保证bean创建的对象唯一
//告诉springMVC拦截器的位置
public class SpringMvcConfig implements WebMvcConfigurer {
@Override
//添加一个拦截器
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(ipCountInterceptor()).addPathPatterns("/**");//"/**表示所有请求"
}
@Bean
public IpCountInterceptor ipCountInterceptor(){
return new IpCountInterceptor();
}
}
运行之后 ,访问任意的功能都可以计数
在自定义starter中pom.xml中加入,mavenclean和install之后可以删除此坐标
org.springframework.boot
spring-boot-configuration-processor
然后在maven中点击clean和install重新编译
就会多出一个json文件
在使用这个starter的yaml配置文件中
就已经可以出现提示了,这些后面的中文都是之前写入的文档注释,所以得多写文档注释
输出之后,没有提示我们要写入的值
在前面生成的json文件中
"hints": [
{
"name": "properties.ip.model",
"values": [
{
"value": "detail",
"description": "详细模式."
},
{
"value": "simple",
"description": "简略模式."
}
]
}
]
这样就可以得出提示了