SpringBoot 接口整理
目录
- 1. ApplicationListener接口
- 2. ApplicationContextAware接口
- 3. InitializingBean接口
- 4. HandlerInterceptor拦截器接口
- 5. WebMvcConfigurer接口
- 6. ErrorPageRegistrar接口
- 7. CommandLineRunner接口
- 8. SpringBootServletInitializer接口
1. ApplicationListener接口
⏹要点
- 继承此接口可以获取Spring容器对象,可以获取容器中的Bean
import com.example.annotation.PayCode;
import com.example.interfacePackage.IPay;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;
@Service("PayService")
public class PayService implements ApplicationListener<ContextRefreshedEvent> {
// key:业务code value:类对象所实现的接口
private static Map<String, IPay> payMap = new HashMap<>();
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();
// 通过注解的方式来获取Bean对象
Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(PayCode.class);
beansWithAnnotation.forEach((key, value) -> {
// key: 类名
// value: 类对象
PayCode annotation = value.getClass().getAnnotation(PayCode.class);
String payCode = annotation.payCode();
// 将code和类对象放入Map中
payMap.put(payCode, (IPay) value);
});
}
}
2. ApplicationContextAware接口
⏹要点
- 继承此接口可以获取Spring容器对象,可以获取容器中的Bean
import com.example.interfacePackage.IPay;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
@Service
public class PayService2 implements ApplicationContextAware {
// Spring applicationContext容器对象
private ApplicationContext applicationContext;
private static final String SUFFIX = "Pay";
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// 初始化applicationContext对象
this.applicationContext = applicationContext;
}
// 对支付方法进行封装
public void toPay(String payCode) {
String beanName = this.getBeanName(payCode);
((IPay) applicationContext.getBean(beanName)).pay();
}
// 根据业务code,动态拼接名称
private String getBeanName(String payCode) {
return payCode + SUFFIX;
}
}
3. InitializingBean接口
⏹要点
- 实现此接口的类拥有初始化Bean的功能
import com.example.interfacePackage.IPayMethod;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
@Service
public class PayService3 implements ApplicationContextAware, InitializingBean {
private ApplicationContext applicationContext;
private List<IPayMethod> payList = null;
// 初始化容器对象
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
// InitializingBean接口说明
// InitializingBean接口为bean提供了属性初始化后的处理方法,它只包括afterPropertiesSet方法,
// 凡是继承该接口的类,在bean的属性初始化后都会执行该方法。
@Override
public void afterPropertiesSet() throws Exception {
if (payList == null) {
payList = new ArrayList<>();
// 获取实现了IPayMethod接口的Bean
Map<String, IPayMethod> beansOfType = applicationContext.getBeansOfType(IPayMethod.class);
// 将类对象添加到payList列表中
beansOfType.forEach((key, value) -> payList.add(value));
}
}
}
4. HandlerInterceptor拦截器接口
⏹要点:
- 我们实现接口所创建的拦截器并不会自动生效
- 需要将自定义拦截器放入实现了
WebMvcConfigurer
接口的配置类中
⏹应用
从session中获取信息打印日志
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class ControllerInterceptor implements HandlerInterceptor {
private static HashMap<String, String> gamenMeiMap;
// 拦截之前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response) {
// 获取浏览器中输入的url
String requestUrl = httpServletRequest.getRequestURI();
HashMap<String, Object> returnValueMap =
(HashMap<String, Object>)JsonUtil.toHashMap(request.getParameter("toParam"));
if (returnValueMap == null) {
return true;
}
// 初期表示 かつ 画面遷移を実行の場合
if (requestUrl.contains("init") && returnValueMap.containsKey("syoriBtn")) {
// 从session中获取用户ID
Object userId = request.getSession().getAttribute("code");
// 获取URL和画面的Map
HashMap<String, String> map = ControllerInterceptor.destGamenMeiAll();
// 根据前台的URL匹配传入的画面
String destName = StringUtil.BLANK;
for (Map.Entry<String, String> entry : map.entrySet()) {
String resUrl = entry.getKey();
if (resUrl == null) {
continue;
}
AntPathRequestMatcher matcher = new AntPathRequestMatcher(resUrl);
if (matcher.matches(request)) {
destName = entry.getValue();
break;
}
}
// 操作ログを出力する
System.out.println("当前访问的画面是" + destName);
}
// 返回true,让程序继续向下执行
return true;
}
// URL所对应画面
public static HashMap<String, String> destGamenMeiAll() {
if (gamenMeiMap == null) {
gamenMeiMap = new HashMap<String, String>();
}
gamenMeiMap.clear();
gamenMeiMap.put("/CSPKyoutsu/**", "共通画面");
gamenMeiMap.put("/CSPLogin/**", "ログイン");
return gamenMeiMap;
}
// 拦截之时
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response) {
// ......
}
// 拦截之后
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response) {
// ......
}
}
5. WebMvcConfigurer接口
参考资料
- SpringBoot—WebMvcConfigurer详解
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@SpringBootConfiguration
public class SpringMVCConfig implements WebMvcConfigurer {
// 指定要排除不过滤的url路径
ArrayList<String> list = new ArrayList<>();
list.add("/admin");
list.add("/admin/login");
// 将我们自定义的拦截器放入此配置类中
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ControllerInterceptor())
// 一般都会使用Spring Security进行具体的拦截和权限控制,下面用法只做参考
// 拦截admin下面的所有的请求
.addPathPatterns("/admin/**")
// 指定某个路径不被拦截
.excludePathPatterns(list);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 访问路径,若访问路径设置为 /image,则访问任何资源都需要添加 /image 前缀
registry.addResourceHandler("/**")
// 添加springmvc默认的静态文件保存路径,如果不添加的话,默认静态保存路径会失效
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/static/")
// 添加我们自定义的静态资源保存路径,这样可以从外部磁盘读取图片
.addResourceLocations("file:E:\\写真\\");
}
// 跨域配置
@Override
public void addCorsMappings(CorsRegistry registry) {
}
}
6. ErrorPageRegistrar接口
参考资料
-
(022)Spring Boot之异常处理的两种方式
-
ErrorPageRegistrar根据不同的错误类型显示网页
⏹要点
- 根据不同的错误返回不同的错误页面
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@Component
public class ErrorConfig implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
String errorPage = "";
if("XXX") {
errorPage = "/ApacheSystemError/init";
} else {
errorPage = "/Error/init";
}
// 400
ErrorPage error400Page = new ErrorPage(HttpStatus.BAD_REQUEST, errorPage);
// 401
ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, errorPage);
// 403
ErrorPage error403Page = new ErrorPage(HttpStatus.FORBIDDEN, errorPage);
// 404
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, errorPage);
// 500
ErrorPage error500Page =
new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, errorPage);
registry.addErrorPages(error400Page, error401Page,
error403Page, error404Page, error500Page);
}
}
7. CommandLineRunner接口
参考资料
- SpringBoot CommandLineRunner接口的使用👍
- Spring boot CommandLineRunner接口使用例子
⏹要点
- 在应用程序启动之后,只会执行一次,此接口一般多用于Spring的批处理
- 可以和@Order注解配合使用,通过该注解指定多个实现了CommandLineRunner接口的类的加载顺序
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableTransactionManagement
public class SpringbootApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// 批处理的具体逻辑调用
IBatchMain batchMain = (IBatchMain) SpringUtil.getBean("XXX");
String[] args1 = new String[]{"03", "99"};
batchMain.runBatch(args1);
}
}
8. SpringBootServletInitializer接口
参考资料
- Spring boot —SpringBootServletInitializer 启动spring boot项目的方式之一
⏹要点
- 如果不继承SpringBootServletInitializer类的话,我们一般会生成jar包,此jar包内内置了Tomcat
- 继承SpringBootServletInitializer类,我们一般会生成war包,然后使用外部的Tomcat来进行配置
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class SpringbootApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
try {
SpringApplication.run(SpringbootApplication.class, args);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// 将当前运行的项目做成一个war包
return builder.sources(SpringbootApplication.class);
}
}