springboot-自己开发start

步骤

命名规范

  • 第三方在建立自己的 Starter 的时候命名规则统一用xxx-spring-boot-starter,
  • 官方提供的 Starter 统一命名方式为spring-boot-starter-xxx。

步骤

  • 新建一个Maven项目,在pom.xml文件中定义好所需依赖;
  • 新建配置类,写好配置项和默认值,使用@ConfigurationProperties指明配置项前缀;
  • 新建自动装配类,使用@Configuration@Bean来进行自动装配;
  • 新建spring.factories文件,用于指定自动装配类的路径;
  • 将starter安装到maven仓库,让其他项目能够引用;
  • 需要提示功能的话,还必须有spring-configuration-metadata.json,通过依赖spring-boot-configuration-processor生成的,发布后一定要删除该依赖,否则会出双份的提示信息。

1、创建项目,写好依赖

  • 删除test依赖和包
  • spring-boot-configuration-processor 最后是要删除的。主要用于生成spring-configuration-metadata.json
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
</dependencies>

2、属性配置类

  • 写好配置项和默认值。并使用@ConfigurationProperties指明配置项前缀,用于加载配置文件对应的前缀配置项:
  • 建议写doc文档,这样在配置时会有提示
  • 如果仅仅添加@ConfigurationProperties,会有报错提示,因为有这个注解,他必须是一个可被管控的bean,先不用管,在IpAutoConfiguration中引入@Import(IpProperties.class)就不会再报错了
  • @Component("ipProperties")可以不用写,但是服务类上使用了别名,这里主要的目的是定义IpProperties的别名

public enum IpModeEnum {
    /**
     * 极简信息
     */
    SIMPLE("simple"),
    /**
     * 详细信息
     */
    DETAIL("detail");
    private final String value;

    IpModeEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}


@Component("ipProperties")
@ConfigurationProperties(prefix = "tools.ip")
public class IpProperties {
    /**
     * 日志显示周期
     */
    private Integer cycle = 5;
    /**
     * 是否周期内重置数据
     */
    private boolean cycleReset = false;
    /**
     * 日志输出模式  detail:详细模式  simple:极简模式
     */
    private String model = IpModeEnum.DETAIL.getValue();

    public IpProperties() {
    }

    public IpProperties(Integer cycle, boolean cycleReset, String model) {
        this.cycle = cycle;
        this.cycleReset = cycleReset;
        this.model = model;
    }

    /**
     * 获取
     * @return cycle
     */
    public Integer getCycle() {
        return cycle;
    }

    /**
     * 设置
     * @param cycle
     */
    public void setCycle(Integer cycle) {
        this.cycle = cycle;
    }

    /**
     * 获取
     * @return cycleReset
     */
    public boolean isCycleReset() {
        return cycleReset;
    }

    /**
     * 设置
     * @param cycleReset
     */
    public void setCycleReset(boolean cycleReset) {
        this.cycleReset = cycleReset;
    }

    /**
     * 获取
     * @return model
     */
    public String getModel() {
        return model;
    }

    /**
     * 设置
     * @param model
     */
    public void setModel(String model) {
        this.model = model;
    }

    public String toString() {
        return "IpProperties{cycle = " + cycle + ", cycleReset = " + cycleReset + ", model = " + model + "}";
    }
}

3、服务类

public class IpCountService {
    /**
     * 统计的集合
     */
    private final Map<String,Integer> ipCountMap = new HashMap<>();
    /**
     * 当前的request对象的注入工作由使用当前starter的工程提供自动装配
     */
    @Resource
    private HttpServletRequest httpServletRequest;
    @Autowired
    private IpProperties ipProperties;
    /**
     * 每次调用当前操作,就记录当前访问的IP,然后累加访问次数,并把数据放到map中
     */
    public void count(){
        //1.获取当前操作的IP地址
        String ip = httpServletRequest.getRemoteAddr();
        //2.根据IP地址从Map取值,并递增
        ipCountMap.merge(ip, 1, Integer::sum);
    }
    @Scheduled(cron = "0/#{ipProperties.cycle} * * * * ?")
    public void print(){

        if(ipProperties.getMode().equals(LogModeEnum.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.printf("|%18s  |%5d  |%n",key,value);
            }
            System.out.println("+--------------------+-------+");
        }else if(ipProperties.getMode().equals(LogModeEnum.SIMPLE.getValue())){
            System.out.println("     IP访问监控");
            System.out.println("+-----ip-address-----+");
            for (String key: ipCountMap.keySet()) {
                System.out.printf("|%18s  |%n",key);
            }
            System.out.println("+--------------------+");
        }

        if(ipProperties.isCycleReset()){
            ipCountMap.clear();
        }
    }
}

3、自动配置类

  • EnableScheduling:开启定时任务
@EnableScheduling
@Import(IpProperties.class)
public class IpAutoConfiguration {
    @Bean
    public IpCountService  ipCountService(){
        return new IpCountService();
    }
}

4、拦截器

public class IpCountInterceptor 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(ipCountInterceptor()).addPathPatterns("/**");
    }

    @Bean
    public IpCountInterceptor ipCountInterceptor(){
        return new IpCountInterceptor();
    }

}

5、新建spring.factories文件,用于指定自动装配类的路径;

  • 路径:src/main/resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.tjhis.ipconfig.config.IpAutoConfiguration

6、新建spring-configuration-metadata.json文件,用于在配置时自动提示;

{
  "groups": [
    {
      "name": "tools.ip",
      "type": "cn.tjhis.ipconfig.config.IpProperties",
      "sourceType": "cn.tjhis.ipconfig.config.IpProperties"
    }
  ],
  "properties": [
    {
      "name": "tools.ip.cycle",
      "type": "java.lang.Integer",
      "description": "日志显示周期",
      "sourceType": "cn.tjhis.ipconfig.config.IpProperties",
      "defaultValue": 5
    },
    {
      "name": "tools.ip.cycle-reset",
      "type": "java.lang.Boolean",
      "description": "是否周期内重置数据",
      "sourceType": "cn.tjhis.ipconfig.config.IpProperties",
      "defaultValue": false
    },
    {
      "name": "tools.ip.mode",
      "type": "java.lang.String",
      "description": "日志输出模式  detail:详细模式  simple:极简模式",
      "sourceType": "cn.tjhis.ipconfig.config.IpProperties"
    }
  ],
  "hints": [
    {
      "name": "tools.ip.mode",
      "values": [
        {
          "value": "detail",
          "description": "详细模式."
        },
        {
          "value": "simple",
          "description": "极简模式."
        }
      ]
    }
  ]
}

6、把其安装到maven仓库,这样其他工程就可以引用了

  • clean
  • install

7、在另一个web工程中引入

<dependency>
	<groupId>cn.tjhis</groupId>
	<artifactId>ipCount-spring-boot-starter</artifactId>
	<version>1.0.1</version>
</dependency>
posted @ 2023-04-02 09:04  his365  阅读(71)  评论(0编辑  收藏  举报