栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

基于黑马的SpringBoot自动配置的ip访问计数器原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于黑马的SpringBoot自动配置的ip访问计数器原理

之前学习springboot自动装配时,了解了如何自己写一个spring-boot-starter进行引入其它项目里,以此来记录,加深记忆,
ip计数器原理: 当别人访问自己的网页时,得到ip地址然后进行记录,若多次访问 则进行+1操作,并打印在控制台

如何自己动手搭建一个xx-spring-boot-starter

如何搭建一个技术starter呢?下面就是一些具体操作,一般自己搭建的starter都是以 xx技术-spring-boot-starter 的形式命名

创建一个springboot项目

首先创建一个spring boot项目 对项目名字和maven坐标进行修改,例如搭一个叫做 ip-count-spring-boot-starter项目
做好命名规范

点击next 后继续点击 把项目创建好后,开始搭基本框架

配置属性类

这里我们设置三个属性
第一个:cycle:多少时间打印一次
第二个:reset属性代表是否每次周期性打印时,是否清空里面存储的值,重新计数
第三个:modle 分为,极简模式(只显示ip地址)和详细模式(显示ip地址和次数)

package com.properties;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;


@Component("ipProperties")
@ConfigurationProperties(prefix = "tools")
public class IpProperties {

    
    private Long cycle=5L;
    
    private Boolean reset=false;
    
    private String model=LogModel.DETAIL.value;

    public Long getCycle() {
        return cycle;
    }

    public void setCycle(Long cycle) {
        this.cycle = cycle;
    }

    public Boolean getReset() {
        return reset;
    }

    public void setReset(Boolean reset) {
        this.reset = reset;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    
    public enum LogModel {
    DETAIL("dateil"),
    SIMPLE("simple");
    private String value;
    LogModel(String value){
        this.value=value;
    }

    public String getValue() {
        return value;
    }
}
}

根据属性类编写逻辑代码

需求是:别人访问地址后获取他的ip地址进行保存后并且对着ip的访问次数也+1操作
利用Map集合进行存储:key是IP地址,value是 该ip访问的次数
count()方法:

    
    public void count(){
//    利用hashmap存储
        //key存在+1 不存在 设置为1
        String ipaddress=request.getRemoteAddr();
        if (ipCountMap.containsKey(ipaddress)){
            ipCountMap.put(ipaddress,ipCountMap.get(ipaddress)+1);
        }else {
            ipCountMap.put(ipaddress,1);
        }
    }

print打印方法()

  
    @Scheduled(cron = "0/#{ipProperties.cycle} * * * * ?")
    public void print(){

//        判断是否是详细模式
    if (ipProperties.getModel().equals(IpProperties.LogModel.DETAIL.getValue())){

        System.out.println("          ip访问监控");
        System.out.println("+----ipaddress----+---num---+");
        Set strings = ipCountMap.keySet();
        for (String string : strings) {
            Integer integer = ipCountMap.get(string);
            System.out.println(String.format("|%15s  |%5d   |", string, integer));
        }
        System.out.println("+-----------------+---------+");

    }//判断是否是简单模式
    else if(ipProperties.getModel().equals(IpProperties.LogModel.SIMPLE.getValue())){
        System.out.println("          ip访问监控");
        System.out.println("+----ipaddress----+");
        Set strings = ipCountMap.keySet();
        for (String string : strings) {
            System.out.println(String.format("|%15s  |", string));
        }
        System.out.println("+-----------------+");
    }

//        判断是否是周期性更新
    if (ipProperties.getReset()){
        ipCountMap.clear();
    }

    }

完整的业务逻辑代码:

package com.service;

import com.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;
import java.util.Set;

public class IpCountService {
//    通过调用该技术的项目进行注入
    @Autowired
private HttpServletRequest request;
private  Map ipCountMap=new HashMap<>();

    
    public void count(){
//    利用hashmap存储
        //key存在+1 不存在 设置为1
        String ipaddress=request.getRemoteAddr();
        if (ipCountMap.containsKey(ipaddress)){
            ipCountMap.put(ipaddress,ipCountMap.get(ipaddress)+1);
        }else {
            ipCountMap.put(ipaddress,1);
        }
    }

    @Autowired
    private IpProperties ipProperties;
    
    @Scheduled(cron = "0/#{ipProperties.cycle} * * * * ?")
    public void print(){

//        判断是否是详细模式
    if (ipProperties.getModel().equals(IpProperties.LogModel.DETAIL.getValue())){

        System.out.println("          ip访问监控");
        System.out.println("+----ipaddress----+---num---+");
        Set strings = ipCountMap.keySet();
        for (String string : strings) {
            Integer integer = ipCountMap.get(string);
            System.out.println(String.format("|%15s  |%5d   |", string, integer));
        }
        System.out.println("+-----------------+---------+");

    }//判断是否是简单模式
    else if(ipProperties.getModel().equals(IpProperties.LogModel.SIMPLE.getValue())){
        System.out.println("          ip访问监控");
        System.out.println("+----ipaddress----+");
        Set strings = ipCountMap.keySet();
        for (String string : strings) {
            System.out.println(String.format("|%15s  |", string));
        }
        System.out.println("+-----------------+");
    }

//        判断是否是周期性更新
    if (ipProperties.getReset()){
        ipCountMap.clear();
    }

    }
}

编写spring.factories和自动配置类引入业务类

第一步编写自动装配类,什么都不用做映入类 和开启定时器就行了

@Configuration
//引入类
@Import(IpCountService.class)
//开启定时器
@EnableScheduling
public class IpAutoConfig {

}

第二步在resource下创建META-INF文件夹创建spring.factories

#自动加载的类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
  com.autoconfig.IpAutoConfig
编写拦截器
package com.interceptor;

import com.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();

        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
}

添加拦截器
package com.config;

import com.interceptor.IpCountInterceptor;
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
public class SpringMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
//注册拦截器,设置拦截路径
        registry.addInterceptor(interceptor()).addPathPatterns("/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
//    把拦截器实例化bean
    @Bean
    public IpCountInterceptor interceptor(){
        return new IpCountInterceptor();
    }
}

设置属性提示语

第一步导包

        
            org.springframework.boot
            spring-boot-configuration-processor
        

导完包后编译一下 然后把在注释掉(目的是防止重复提示)
找到编译文件下的json文件:

打开application.yml设置属性时,就会有提示语了

设置属性提示选择

打开之前的json文件 找到最底部的属性:

{
  "groups": [
    {
      "name": "tools",
      "type": "com.properties.IpProperties",
      "sourceType": "com.properties.IpProperties"
    }
  ],
  "properties": [
    {
      "name": "tools.cycle",
      "type": "java.lang.Long",
      "description": "周期数,多少秒打印一次",
      "sourceType": "com.properties.IpProperties",
      "defaultValue": 5
    },
    {
      "name": "tools.model",
      "type": "java.lang.String",
      "description": "打印模式,默认详细",
      "sourceType": "com.properties.IpProperties"
    },
    {
      "name": "tools.reset",
      "type": "java.lang.Boolean",
      "description": "每次周期是否重置ip信息",
      "sourceType": "com.properties.IpProperties",
      "defaultValue": false
    }
  ],
  "hints": []
}

修改成:

{
  "groups": [
    {
      "name": "tools",
      "type": "com.properties.IpProperties",
      "sourceType": "com.properties.IpProperties"
    }
  ],
  "properties": [
    {
      "name": "tools.cycle",
      "type": "java.lang.Long",
      "description": "周期数,多少秒打印一次",
      "sourceType": "com.properties.IpProperties",
      "defaultValue": 5
    },
    {
      "name": "tools.model",
      "type": "java.lang.String",
      "description": "打印模式,默认详细",
      "sourceType": "com.properties.IpProperties"
    },
    {
      "name": "tools.reset",
      "type": "java.lang.Boolean",
      "description": "每次周期是否重置ip信息",
      "sourceType": "com.properties.IpProperties",
      "defaultValue": false
    }
  ],
  "hints": [{
    "name": "tools.model",
    "values":[{
      "value": "simple",
      "description": "极简模式"
    },{
      "value": "detail",
      "description": "详细模式"
    }]
  }]
}

选择的值就会出现提示语了

清除(clean)安装(install) 到本地仓库

ctrl+鼠标点击maven 生命周期的 clean 和install 在点击运行

创建一个springbootweb项目引入刚刚安装到仓库的项目坐标坐标


然后配置yml文件

启动项目就会发现会自动打印了

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/847802.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号