自定义一个 starter
1、什么是 starter
Starter是Spring Boot项目中的一个重要概念,它是一种方便开发者快速集成和配置常用功能模块的依赖包。Starter实质上是一个Maven项目,它打包了一组相关的依赖和默认配置,以便于在Spring Boot应用中快速引入和使用。
Spring Boot提供了大量的官方Starter,例如spring-boot-starter-web、spring-boot-starter-data-jpa、spring-boot-starter-security等,还有第三方或社区提供的各种Starter。这些Starter使得在Spring Boot项目中引入和集成常用功能模块变得非常便捷,开发者可以快速搭建起一个功能完善的应用。
本文将通过一个简单案例,可以自定义一个属于自己的 starter
2、写一个功能类
1、建一个模块,名叫 ip-counter-boot-sterter
2、写 service 层,先写接口,再写实现类
package service;
public interface IpCounterService {
void record();
}
// 实现类就是根据ip统计访问次数
package service.impl;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import service.IpCounterService;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class IpCounterServiceImpl implements IpCounterService {
@Autowired
private HttpServletRequest request;
private Map<String,Integer> map = new HashMap<>();
@Override
public void record() {
String ip = request.getRemoteAddr();
Integer i = map.get(ip);
i = Objects.isNull(i) ? 1 : i + 1;
map.put(ip,i);
map.forEach((key,val) -> {
System.out.println("ip : " + key + "\t count : " + val);
});
}
}
3、写自动配置类
也很简单,就是写一个能返回功能类的配置类
package config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import service.IpCounterService;
import service.impl.IpCounterServiceImpl;
@Configuration
public class IpAutoConfiguration {
@Bean
public IpCounterService ipCounterService() {
return new IpCounterServiceImpl();
}
}
4、把自动配置类引入到 Spring 环境中(重要)
步骤也很简单,就是在 resources 目录下创建文件夹
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(注意 spring3 之后是这个,之前是 spring.factories,这个在2.7被废止)文件里面的内容是我们写的配置类的全路径,接着就可以在我们需要使用的模块添加依赖,再通过依赖注入的方式进行使用。
文件中的内容就是自动配置类的全路径名
5、在 maven 中安装,并添加依赖到测试模块
创建一个测试模块,就是需要引入 starter 包的模块:
然后 dependencies 里面进行引入:
6、在测试模块进行测试
package com.example.testIpCounter.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import service.IpCounterService;
@RestController
public class IndexController {
@Autowired
private IpCounterService ipCounterService;
@GetMapping("/starter")
public String index() {
ipCounterService.record();
return "hello,starter !!!!!!";
}
@RequestMapping("/aaa")
public String aaa() {
return "aaa";
}
}
测试结果:
http://127.0.0.1:8082/starter
7、写一个拦截器功能,让它更像 starter
package interceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import service.IpCounterService;
public class IpCounterInterceptor implements HandlerInterceptor {
@Autowired
private IpCounterService ipCounterService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
ipCounterService.record();
return true;
}
}
package config;
import interceptor.IpCounterInterceptor;
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("/**");
}
@Bean
public IpCounterInterceptor interceptor() {
return new IpCounterInterceptor();
}
}
重新 clean & install ,测试模块就算不显示调用 record 方法,也会有监控 ip 的功能。