自定义starter案例——统计独立IP访问次数
文章目录
- 自定义starter案例——统计独立IP访问次数
- ip计数业务功能开发
- 定时任务报表开发
- 使用属性配置功能设置功能参数
- 配置调整
- 自定义拦截器
- 开启yml提示功能
ip计数业务功能开发
public class IpCountService {private Map<String,Integer> ipCountMap = new HashMap<String,Integer>();@Autowired// 当前的request对象的诸如工作由当前的starter的工程提供自动装配private HttpServletRequest httpServletRequest;public void count(){// 每次调用当前操作,就记录当前访问的ip,然后累加访问次数// 1.获取当前操作的ip地址String ip = httpServletRequest.getRemoteAddr();System.out.println("----------------------------------" + ip);// 2.根据ip地址从map取值,并递增ipCountMap.put(ip,ipCountMap.get(ip)==null? 0+1 : ipCountMap.get(ip) + 1);}
}
使用@import注入bean也可以
public class IpAutoCinfiguration {@Beanpublic IpCountService ipCountService(){return new IpCountService();}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.itcast.autoconfig.IpAutoCinfigur
@Autowiredprivate IpCountService ipCountService;@GetMapping("/{currentPage}/{pageSize}")public R getPage(@PathVariable int currentPage,@PathVariable int pageSize,Book book){ipCountService.count();IPage<Book> page = bookService.getPage(currentPage, pageSize,book);// 如果当前页码值大于总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值if (currentPage > page.getPages()){page = bookService.getPage((int)page.getPages(), pageSize,book);}return new R(true,page);}
定时任务报表开发
@EnableScheduling
public class IpAutoCinfiguration {@Beanpublic IpCountService ipCountService(){return new IpCountService();}
}
@Scheduled(cron = "0/5 * * * * ?")public void print(){System.out.println(" ip访问监控");System.out.println("+-----ip-address-----+---+");for (Map.Entry<String, Integer> entry : ipCountMap.entrySet()) {String key = entry.getKey();Integer value = entry.getValue();System.out.println(String.format("|%18s |%5d |",key,value));}System.out.println("+--------------------+---+");}
使用属性配置功能设置功能参数
@ConfigurationProperties(prefix = "tools.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 Long getCycle() {return cycle;}public void setCycle(Long cycle) {this.cycle = cycle;}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;}
}
@EnableScheduling
@EnableConfigurationProperties(IpProperties.class)
public class IpAutoCinfiguration {@Beanpublic IpCountService ipCountService(){return new IpCountService();}
}
@Autowiredprivate IpProperties ipProperties;@Scheduled(cron = "0/5 * * * * ?")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()) {String key = entry.getKey();Integer value = entry.getValue();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访问监控");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();}}
tools:ip:
# cycle: 1
# cycle-reset: true
# model: "simple"
配置调整
自定义bean名称,原因如下:
因为我们的周期属性是要配置在cron表达式中的,但是如何获取配置的属性,需要读取到bean,但是直接找bean的话,名字特别长,而且这个bean的名字和beanName的生成器生成的名称恰巧与我们的表达式冲突,所以就曲线救国,自己给bean起个名字。
但是自己起个名字就出现了另一个问题,我们的配置类上以前是使用@EnableConfigurationProperties(IpProperties.class)注册的IpProperties的bean,现在IpProperties被注册了两次bean,又有了新的问题,所以我们在IpAutoCinfiguration上把以前的EnableConfigurationProperties的方式换成Import的方式导入bean。
自定义拦截器
public class IpCountInterceptor implements HandlerInterceptor {@Autowiredprivate IpCountService ipCountService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {ipCountService.count();return true;}}
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {@Beanpublic IpCountInterceptor ipCountInterceptor(){return new IpCountInterceptor();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(ipCountInterceptor()).addPathPatterns("/**");}
}
写完后要在启动类上加上拦截器哟!,使用Import加进去。
@EnableScheduling
//@EnableConfigurationProperties(IpProperties.class)
@Import({IpProperties.class, IpCountInterceptor.class, SpringMvcConfig.class})
public class IpAutoCinfiguration {@Beanpublic IpCountService ipCountService(){return new IpCountService();}
}
开启yml提示功能
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-configuration-processor</artifactId>-->
<!-- </dependency>-->
用这个坐标生成spring-configuration-metadata,也就是加上这个坐标,然后clean-install,就会生成这个文件,把这个文件从target目录中找到并且提出来,放到我们的配置目录下,这个坐标就可以注释了,因为上线用不到。
"hints": [{"name": "tools.ip.model","values": [{"value": "detail","description": "详细模式."},{"value": "simple","description": "极简模式."}]}]
提示功能默认是[],自己照着样子配就行了。