執行順序
在一個方法只被一個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();
}
}
}