Spring boot 使用AOP 通过注解处理404异常
2019-11-09
1,983 views
0 min read
这是一篇Spring boot aop的简单应用。
应用场景
我在我的应用中,如果尝试获取一个不存在的资源,例如GET /user/123
,当不存在123
这个用户时,我会返回404错误给前端。
以前的做法是在service
层获取资源,资源为null
时抛出NotFoundException
异常。久而久之代码里就会充斥着大量的重复判断的代码,例如
ArticleDO articleDO = articleMapper.getArticle(articleId);
if (articleDO == null) {
throw Exceptions.notFoundException;
}
这明显不美观,于是我通过aop的方式用一行注解@NotFound
实现了上面的效果,只要SQL查询结果为null
,即抛出异常。
/**
* 获取文章详细
* @param id 文章id
* @return 文章详细
* @throws BaseNotFoundException not found
*/
@NotFound
@Select("SELECT * FROM db_article WHERE article_id=#{articleId}")
ArticleDO getArticle(Integer id) throws BaseNotFoundException;
引入包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
定义切点
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface NotFound {
Class<?> notFoundExceptionClz() default BaseNotFoundException.class;
}
@Aspect
@Component
public class NotFoundAop {
@Pointcut("@annotation(nf)")
public void notFound(NotFound nf) {
}
}
以上是通过注解@annotation
的方式定义了一个切点,除了使用注解,还可以使用execution
的方式指定包、类、方法等。
spring AspectJ的Execution表达式
AOP的5种通知
- before(前置通知): 在方法开始执行前执行
- after(后置通知): 在方法执行后执行
- afterReturning(返回后通知): 在方法返回后执行
- afterThrowing(异常通知): 在抛出异常时执行
- around(环绕通知): 在方法执行前和执行后都会执行
执行顺序
around > before > around > after > afterReturning
代码实现
因为要对返回值进行判断,所以用了@AfterReturning
通知,returning
定义的是方法返回值。
@Aspect
@Component
public class NotFoundAop {
@Pointcut("@annotation(nf)")
public void notFound(NotFound nf) {
}
@AfterReturning(returning = "ret", pointcut = "notFound(nf)", argNames = "joinPoint,ret,nf")
public void doNotFound(JoinPoint joinPoint, Object ret, NotFound nf) throws Exception {
if (ret != null) {
return;
}
if (BaseNotFoundException.class.isAssignableFrom(nf.notFoundExceptionClz())) {
throw (BaseNotFoundException) nf.notFoundExceptionClz().getDeclaredConstructor().newInstance();
} else {
throw Exceptions.notFoundException;
}
}
}
我在@NotFound
注解中加了notFoundExceptionClz
参数,可以选填抛出的异常,不填则默认抛出Exceptions.notFoundException
。
这只是一个简单的不能再简单的demo,AOP的功能很强大,能做到的事情也非常的多。如果项目中出现了大量重复不美观的代码,就要考虑是否可以靠一些方式简化了。
Previous Post
Windows管理右键菜单
Next Post
Spring boot 项目开启proxy代理
Or you can contact me by Email