Spring让人眼前一亮的11个小技巧

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

Spring让人眼前一亮的11个小技巧

文章插图
1.自定义拦截器spring mvc拦截器根spring拦截器相比,它里面能够获取HttpServletRequestHttpServletResponse等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接口结果直接报错:
Spring让人眼前一亮的11个小技巧

文章插图
what?用户能直接看到错误信息?
这种交互方式给用户的体验非常差,为了解决这个问题,我们通常会在接口中捕获异常:
@GetMapping("/add")public String add() {String result = "成功";try {int a = 10 / 0;} catch (Exception e) {result = "数据异常";}return result;}接口改造后,出现异常时会提示:“数据异常” , 对用户来说更友好 。
看起来挺不错的,但是有问题 。。。
如果只是一个接口还好,但是如果项目中有成百上千个接口,都要加上异常捕获代码吗?

推荐阅读