当前位置: 首页 > news >正文

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接口

参考资料

  1. 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接口

参考资料

  1. (022)Spring Boot之异常处理的两种方式

  2. 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接口

参考资料

  1. SpringBoot CommandLineRunner接口的使用👍
  2. 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接口

参考资料

  1. 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);
    }
}

相关文章:

  • SpringBoot工程打包与发布运行
  • 芒格-“永远不要有受害者心态”
  • 【位运算】leetcode 190. 颠倒二进制位
  • nexus on k8s最佳实战
  • LeetCode 每日一题 2022/8/29-2022/9/4
  • webpack定制化 高级配置[热更新、热打包、别名、调试]
  • 外贸员需要知道的那些事儿
  • c++11 多线程支持 (std::shared_future)
  • webpack定制化 基础配置[基础、配置、初运行]
  • mysql基本语句:DQL(数据查询语言)
  • Android | 通过URL获取网络图片Bitmap格式
  • SpringCloud-01 Rest学习环境搭建笔记
  • 基于APB与I2C的多主多从架构设计 - Function Description
  • R语言 ggdendro_谱系图
  • Kafka原理及概念解释
  • EventListener原理
  • extract-text-webpack-plugin用法
  • HTML5新特性总结
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • JavaScript设计模式之工厂模式
  • Java多线程(4):使用线程池执行定时任务
  • Java应用性能调优
  • jdbc就是这么简单
  • k个最大的数及变种小结
  • Sublime Text 2/3 绑定Eclipse快捷键
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 技术胖1-4季视频复习— (看视频笔记)
  • 携程小程序初体验
  • 在Unity中实现一个简单的消息管理器
  • 怎么把视频里的音乐提取出来
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ​2021半年盘点,不想你错过的重磅新书
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • #1015 : KMP算法
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (MATLAB)第五章-矩阵运算
  • (pytorch进阶之路)扩散概率模型
  • (二)构建dubbo分布式平台-平台功能导图
  • (算法设计与分析)第一章算法概述-习题
  • (转)LINQ之路
  • (转)重识new
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .NET MVC第三章、三种传值方式
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • ??在JSP中,java和JavaScript如何交互?
  • @DataRedisTest测试redis从未如此丝滑
  • @EnableWebMvc介绍和使用详细demo
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [20161214]如何确定dbid.txt
  • [20180129]bash显示path环境变量.txt
  • [20181219]script使用小技巧.txt