springboot项目的aop编程测试
-
业务需求
在之前的写的代码中,有部分方法写的不够完美。我的项目中的问题是,像一些操作类(新增、修改、删除)的方法没有给前端一个明显的反馈响应(比如新增成功还是失败)。所以我就想着给这些方法能不能加个注解,我们想办法监听这些方法给这些方法以切面的方式切进去一些代码。说干就干。 -
实现流程
导入aop的相关jar包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjtools -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
创建一个注解类
package org.jiale.aop;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.METHOD})
@Documented
public @interface Operation {
/** 操作成功提示 */
String success() default "操作成功";
/** 操作失败提示 */
String error() default "操作失败";
}
创建自定义监听类
package org.jiale.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 尝试自己写一个aop
* @author ren
* @date 2021年10月08日 14:58:56
*/
@Aspect
@Component
public class OperationListener {
private static final Logger log = LoggerFactory.getLogger(OperationListener.class);
//植入Advice的触发条件
@Pointcut("@annotation(org.jiale.aop.Operation)")
private void addTaskAction(){
}
//环绕增强
@Around("addTaskAction()")
public Object aroundInterviewTask(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("拦截到了" + joinPoint.getSignature().getName() + "方法...");
log.info("@Around : 环绕增强,未执行方法之前...");
log.info("这里最先执行,第一步哦!!!...");
Object proceed = joinPoint.proceed(joinPoint.getArgs());
log.info("这里是第五步,终于回到环绕了...");
log.info("@Around : 环绕增强结束,我浪完了...");
return proceed;
}
//前置增强
@Before("addTaskAction()")
public void beforeInterviewTask(JoinPoint joinPoint){
log.info("@Before : 前置增强...");
log.info("这里是第二步,环绕执行但未执行目标方法前执行...");
}
//方法正常退出时执行
@AfterReturning(returning="result",value="addTaskAction()")
public void afterReturningInterviewTask(JoinPoint joinPoint, Object result){
log.info("@AfterReturning : 方法正常退出时执行...");
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
Method method = ms.getMethod();
Operation operation = method.getAnnotation(Operation.class);
String success = operation.success();
log.info("得到想要表示的操作状态为:{}",success);
log.info("这里是第三步,目标方法执行完并未立即回到环绕方法,而是先来到这里...");
}
//异常抛出增强
@AfterThrowing(throwing="ex",value="addTaskAction()")
public void afterThrowingInterviewTask(JoinPoint joinPoint, Throwable ex){
log.info("@AfterThrowing : 方法异常时执行...");
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
Method method = ms.getMethod();
Operation operation = method.getAnnotation(Operation.class);
String error = operation.error();
log.info("得到想要表示的操作状态为:{}",error);
log.info("这里是第三步,目标方法执行完并未立即回到环绕方法,而是先来到这里...");
}
//final增强,不管是抛出异常或者正常退出都会执行
@After("addTaskAction()")
public void afterInterviewTask(JoinPoint joinPoint){
log.info("@After : 方法执行完必执行...");
log.info("这里是第四步,从第三步出来继而来到这里...");
}
}
给要监听的方法加上自定义注解
/**
* 修改合同关键字匹配库
* @param library
* @return
*/
@PostMapping("/edit")
@ResponseBody
@Operation
public Result editSave(CostKeywordMatchLibrary library){
return toAjax(costKeywordMatchLibraryService.update(library));
}
测试结果
注意:这里是springboot项目,记得要把加@Aspect的监听类交给框架管 理,否则项目不报错也切不进去。如果项目是springMVC + spring的话,要加入配置:
<!--开启AOP的注解支持-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
最好加到springmvc.xml文件中去,不要加到springApplication.xml文件中。理论上如果切的是service层的话是可以加到springApplication.xml文件的,但好多人都切不到,我也没测。但加到springmvc.xml文件中是肯定没问题的。