执行顺序
在一个方法只被一个aspect类拦截时,aspect类内部的+advice+将按照以下的顺序进行执行:
正常情况:
异常情况:
功能描述
在方法执行前,判断任务是否开启,若开启,返回前端,提示任务已开启,并阻止方法执行。
前端请求
function testSchdule() {
$.ajax({
url: "/system/test/testSchdule",
type: "get",
dataType: "json",
data: {},
success: function (r) {
if (r.code != 0) {
layer.msg(r.msg);
} else {
layer.msg(r.msg);
}
}
})
}
后端写法
/**
* 测试
*/
@GetMapping("/testSchdule")
@ResponseBody
@Task(name = "测试",isManual = true)
public R testSchdule() {
return R.ok();
}
注解配置:
1.配置注解@Task:
@Target({ElementType.METHOD}) // 作用在方法上
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Documented // 说明该注解将被包含在javadoc中
public @interface Task{
/**
* 名称
*/
String name() default "";
/**
* 是否允许手动执行
*/
boolean isManual() default false;
}
2.配置Aspect
分析功能:1.只要在方法执行前,判断任务是否开启,2.将判断结果反馈给前端,3.在满足阻止方法执行时,阻止方法执行
所以可以选择前置通知或环绕通知
但是,在前置方法用return的方法无法阻止原方法的执行。该处的return 只是结束了目标方法执行前的检验方法而已,而不是结束目标方法。不过,可以抛出异常来阻止(不是我想要的)。我测试过前置通知,是可以向前端返回提示语的。
最终选择用环绕通知
@Aspect
@Component
@Slf4j
public class TaskAspect {
@Resource
private JobService jobService;
// 切入点签名
@Pointcut("@annotation(cc.jz.elm.common.task.anno.Task)")
private void cut() {
}
@Around("cut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
//从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) pjp.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
//获取操作
Task task= method.getAnnotation(Task.class);
String name = task.jobName();
boolean isManual = task.isManual();
// 从数据查询该任务
TaskDO taskDO = jobService.getJobByName(name);
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
if (taskDO == null) {
//JSONUtils.beanToJson:是自己写的,把对象转换为json字符串的方法
returnJson(response, JSONUtils.beanToJson(R.error(CodeMsg.JOB_EXIST)));
log.info("该任务不存在,请新建任务");
return null;
}
// 继续执行方法
return pjp.proceed();
}
public static void returnJson(HttpServletResponse response, String json) throws Exception {
PrintWriter writer = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=utf-8");
try {
writer = response.getWriter();
writer.print(json);
} catch (IOException e) {
log.info(e.getMessage());
} finally {
if (writer != null)
writer.close();
}
}
}