自定义一个计数ip访问次数的starter
1、定义自动装配类
说明: 自动装配类 的作用相当于启动类,自动装配的入口。starter本身是不用启动的,所以说要调用者项目来加载这个自动配置类来注册bean,所有的bean都要经过这里注册bean
@EnableScheduling
//@EnableConfigurationProperties(IpProperties.class)
@Import({IpProperties.class, SpringMvcConfig.class})
public class IpAutoConfiguration {
@Bean
public IpCountService ipCountService() {
return new IpCountService();
}
}
2、创建spring.factories文件
在resources下META-INF目录下创建 spring.factories文件
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
asia.weizhan.autoconfig.IpAutoConfiguration
3、编写业务代码
public class IpCountService {
private Map<String,Integer> ipCountMap = new HashMap<>();
@Autowired
//由使用者工程自动装配
private HttpServletRequest request;
@Autowired
private IpProperties ipProperties;
public void count(){
String ip = request.getRemoteAddr();
//根据ip递增
Integer count = ipCountMap.get(ip);
if (count == null){
ipCountMap.put(ip, 1);
}else {
ipCountMap.put(ip, count + 1);
}
}
@Scheduled(cron = ("0/#{ipProperties.cycle} * * * * ?"))
public void print(){
if (ipProperties.getModel().equals(IpProperties.LogModel.DETAIL.getValue())){
System.out.println(" ip访问监控 ");
System.out.println("+------ip-address------+--num--+");
for (Map.Entry<String, Integer> entry : ipCountMap.entrySet()) {
System.out.println(String.format("|%18s |%5d |",entry.getKey(),entry.getValue()));
}
System.out.println("+----------------------+-------+");
}else if (ipProperties.getModel().equals(IpProperties.LogModel.SIMPLE.getValue())){
System.out.println(" ip访问监控 ");
System.out.println("+------ip-address------+");
for (String key : ipCountMap.keySet()) {
System.out.println(String.format("|%18s |",key));
}
System.out.println("+----------------------+");
}
if (ipProperties.getCycleReset()){
ipCountMap.clear();
}
}
}
4、创建属性类
用于读取 properties文件或者yml等配置文件封装成java bean
@Component("ipProperties")
@ConfigurationProperties(prefix = "tools.ip")
public class IpProperties {
/**
* 日志显示周期
*/
private Long cycle = 5L;
/**
* 是否周期内重置数据
*/
private Boolean cycleReset = false;
/**
* 日志输出模式
* detail:详细模式
* simple:简单模式
*/
private String model = LogModel.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;
}
public enum LogModel {
DETAIL("detail"),
SIMPLE("simple");
private String Value;
LogModel(String value) {
Value = value;
}
public String getValue() {
return Value;
}
}
}
5、编写拦截器
拦截请求执行统计ip工作
public class IpInterceptor implements HandlerInterceptor {
@Autowired
private IpCountService ipCountService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
ipCountService.count();
return true;
}
}
在配置类中配置拦截器才能使用拦截器
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor()).addPathPatterns("/**");
}
@Bean
public IpInterceptor interceptor(){
return new IpInterceptor();
}
}
6、配置文件提示功能
在resources下META-INF目录下创建 spring-configuration-metadata.json文件
{
"groups": [
{
"name": "tools.ip",
"type": "asia.weizhan.properties.IpProperties",
"sourceType": "asia.weizhan.properties.IpProperties"
}
],
"properties": [
{
"name": "tools.ip.cycle",
"type": "java.lang.Long",
"description": "日志显示周期",
"sourceType": "asia.weizhan.properties.IpProperties",
"defaultValue": 5
},
{
"name": "tools.ip.cycle-reset",
"type": "java.lang.Boolean",
"description": "是否周期内重置数据",
"sourceType": "asia.weizhan.properties.IpProperties",
"defaultValue": false
},
{
"name": "tools.ip.model",
"type": "java.lang.String",
"description": "日志输出模式 detail:详细模式 simple:简单模式",
"sourceType": "asia.weizhan.properties.IpProperties"
}
],
"hints": [
{
"name": "tools.ip.model",
"values": [
{
"value": "detail",
"description": "详细模式."
},
{
"value": "simple",
"description": "简单模式."
}
]
}
]
}
7、使用
直接导入这个starter包即可