自定义starter案例——统计独立IP访问次数

自定义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": "极简模式."}]}]

提示功能默认是[],自己照着样子配就行了。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/255557.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

720度vr虚拟家居展厅提升客户的参观兴致

VR虚拟展厅线上3D交互展示的优势有以下几点&#xff1a; 打破了场馆的展示限制&#xff0c;可展示危险性制品、珍贵稀有物品、超大型设备等&#xff0c;同时提供了更大的展示空间和更丰富的展示内容。 可提供企业真实环境的实时VR全景参观&#xff0c;提升潜在客户信任度。 提供…

AMD 发布新芯片MI300,支持训练和运行大型语言模型

AMD 宣布推出 MI300 芯片&#xff0c;其 Ryzen 8040移动处理器将于2024年用于笔记本电脑。 AMD官方网站&#xff1a;AMD ׀ together we advance_AI AMD——美国半导体公司专门为计算机、通信和消费电子行业设计和制造各种创新的微处理器&#xff08;CPU、GPU、主板芯片组、电…

泳道图绘制全攻略,一图胜千言,快速上手

泳道图是一种流程图的形式&#xff0c;通过在不同的泳道中展示不同的参与者&#xff0c;帮助我们更好地理解和分析流程。它是一种非常有用的工具&#xff0c;可以帮助我们在团队协作、流程管理和问题解决等方面取得更好的效果。 1. 泳道图的定义 泳道图是一种以泳道为基础的流程…

刷机操作小记

步骤&#xff1a; 一.刷机 1.先找到刷机包中的刷机命令&#xff0c;然后用sudo的权限对其执行。 2.之后 先短接&#xff0c;再插USB 短接具体图片如下&#xff08;焊口和大板子&#xff09; 此时等待刷机程序执行完毕就可以完成刷机了。 &#xff08;./fh.sh&#xff09; …

指针(四)

因为前期在学驱动&#xff0c;所以花了一天时间借鉴了别的资料&#xff0c;把本科学的C语言捡起来。 指针的基本概念 堆栈有栈顶指针&#xff0c;队列有头指针和尾指针&#xff0c;这些概念中的"指针"本质上是一个整数&#xff0c;是数组的索引&#xff0c;通过指针…

微信小程序收款手续费多少,怎么降低?

在竞争激烈、各行各业都如此内卷的当下&#xff0c;商家需要不断寻求提高利润的方法。所谓开源节流&#xff0c;既要学会提高利润率&#xff0c;也要学会节省成本&#xff0c;毕竟钱是挣出来的&#xff0c;同时也是省出来的。作为一个经常使用收款工具的商家&#xff0c;很多人…

命令查询pg 数据库版本,并且分析结果行各代表什么意思

目录 1 问题2 实现 1 问题 命令查询pg 数据库版本&#xff0c;并且分析结果行各代表什么意思 2 实现 SELECT version(); PostgreSQL 11.7 (Debian 11.7-2.pgdg1001) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit这是一条关于 PostgreSQL 数据库…

Java 线程池到底是如何复用线程的

原理概述 其实 Java 线程池的实现原理很简单&#xff0c;说白了就是一个线程集合 workerSet 和一个阻塞队列 workQueue。 当用户向线程池提交一个任务时&#xff0c;线程池会先将任务放入 workQueue 中。workerSet 中的线程会不断的从 workQueue 中获取线程然后执行。当 work…

软件设计中如何画各类图之六状态图:生动呈现对象生命周期状态转换的重要工具

目录 1 状态图简介2 状态图的符号及说明2.1 状态&#xff08;State&#xff09;2.2 转移&#xff08;Transition&#xff09;2.3 起始状态与终止状态2.4 动作&#xff08;Action&#xff09; 3 画状态图的步骤3.1 确定对象3.2 定义状态3.3 标识转移3.4 标注动作3.5 添加起始和结…

L1-026:I Love GPLT

题目描述 这道超级简单的题目没有任何输入。 你只需要把这句很重要的话 —— “I Love GPLT”——竖着输出就可以了。 所谓“竖着输出”&#xff0c;是指每个字符占一行&#xff08;包括空格&#xff09;&#xff0c;即每行只能有1个字符和回车。 输入样例&#xff1a; 无输出样…

Java中lambda表达式的使用

&#x1f495;"我不要麻木的死去"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;Java中lambda表达式的使用 一.背景 lambda表达式是Java SE 8中一个重要的新特性&#xff0c;允许你使用一个表达式来代替功能接口。lambda表达式可以看作一个没有返…

Linux | tar,bc,uname指令

Linux | tar&#xff0c;bc&#xff0c; 文章目录 Linux | tar&#xff0c;bc&#xff0c;tar指令【重要】bc指令uname –r指令 tar指令【重要】 tar [-cxtzjvf] 文件与目录 … 参数&#xff1a; -c &#xff1a;建立一个压缩文件的参数指令(create 的意思)&#xff1b;-x &am…