前言我们一说到spring,可能第一个想到的是 IOC
(控制反转) 和 AOP
(面向切面编程) 。
没错,它们是spring的基石 , 得益于它们的优秀设计,使得spring能够从众多优秀框架中脱颖而出 。
除此之外,我们在使用spring的过程中,有没有发现它的扩展能力非常强
。由于这个优势的存在 , 让spring拥有强大的包容能力,让很多第三方应用能够轻松投入spring的怀抱 。比如:rocketmq、mybatis、redis等 。
今天跟大家一起聊聊,在Spring中最常用的11个扩展点 。

文章插图
1.自定义拦截器spring mvc拦截器根spring拦截器相比,它里面能够获取
HttpServletRequest
和HttpServletResponse
等web对象实例 。spring mvc拦截器的顶层接口是:
HandlerInterceptor
,包含三个方法:- preHandle 目标方法执行前执行
- postHandle 目标方法执行后执行
- afterCompletion 请求完成时执行
HandlerInterceptor
接口的实现类HandlerInterceptorAdapter
类 。假如有权限认证、日志、统计的场景,可以使用该拦截器 。
第一步,继承
HandlerInterceptorAdapter
类定义拦截器:public class AuthInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {String requestUrl = request.getRequestURI();if (checkAuth(requestUrl)) {return true;}return false;}private boolean checkAuth(String requestUrl) {System.out.println("===权限校验===");return true;}}
第二步,将该拦截器注册到spring容器:@Configurationpublic class WebAuthConfig extends WebMvcConfigurerAdapter {@Beanpublic AuthInterceptor getAuthInterceptor() {return new AuthInterceptor();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor());}}
第三步,在请求接口时spring mvc通过该拦截器,能够自动拦截该接口 , 并且校验权限 。2.获取Spring容器对象在我们日常开发中,经常需要从Spring容器中获取Bean,但你知道如何获取Spring容器对象吗?
2.1 BeanFactoryAware接口
@Servicepublic class PersonService implements BeanFactoryAware {private BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}public void add() {Person person = (Person) beanFactory.getBean("person");}}
实现BeanFactoryAware
接口,然后重写setBeanFactory
方法,就能从该方法中获取到spring容器对象 。2.2 ApplicationContextAware接口
@Servicepublic class PersonService2 implements ApplicationContextAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}public void add() {Person person = (Person) applicationContext.getBean("person");}}
实现ApplicationContextAware
接口,然后重写setApplicationContext
方法 , 也能从该方法中获取到spring容器对象 。2.3 ApplicationListener接口
@Servicepublic class PersonService3 implements ApplicationListener<ContextRefreshedEvent> {private ApplicationContext applicationContext;@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {applicationContext = event.getApplicationContext();}public void add() {Person person = (Person) applicationContext.getBean("person");}}
3.全局异常处理以前我们在开发接口时,如果出现异常,为了给用户一个更友好的提示 , 例如:@RequestMapping("/test")@RestControllerpublic class TestController {@GetMapping("/add")public String add() {int a = 10 / 0;return "成功";}}
如果不做任何处理请求add接口结果直接报错:
文章插图
what?用户能直接看到错误信息?
这种交互方式给用户的体验非常差,为了解决这个问题,我们通常会在接口中捕获异常:
@GetMapping("/add")public String add() {String result = "成功";try {int a = 10 / 0;} catch (Exception e) {result = "数据异常";}return result;}
接口改造后,出现异常时会提示:“数据异常” , 对用户来说更友好 。看起来挺不错的,但是有问题 。。。
如果只是一个接口还好,但是如果项目中有成百上千个接口,都要加上异常捕获代码吗?
推荐阅读
- Spring Cloud Consul 入门指引
- 原神怎么让正机之神瘫痪
- 一个 dubbo 和 springboot 的兼容性问题
- 一篇文章带你掌握主流基础框架——Spring
- 【持久层框架】- SpringData - JPA
- SpringBoot的starter到底是什么?
- Springboot 之 HandlerMethodReturnValueHandler 运用
- Spring mvc源码分析系列--Servlet的前世今生
- spring cron表达式源码分析
- QQ怎么建群啊(qq建群怎么让人变多)