用到的AOP注解:@Aspect @Pointcut @After
首先看一下如何调用自定义注解:
@MyLog(module="老师模块", method="查询全部")
@RequestMapping("/all")
public List<Teacher> all(){
List<Teacher> ts = teacherSrv.getAll();
return ts;
}
解读:@MyLog是自定义注解类,其中有2个参数(module和method),配置后,调用方法,随后自动进如自定义日志处理(存数据库、打印等操作)
实现方式(4步):
1.引入AOP模块
<!--springBoot AOP-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.定义自定义注解
package com.wyq.springBoot.aop;
import java.lang.annotation.*;
/**
* 自定义操作日志标签,模块名和方法名
* */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyLog {
String module() default "";
String method() default "";
}
3.定义AOP
package com.wyq.springBoot.aop;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class MyLogAction {
/**
* @Resource(name = "logService")
* private MyLogService logService;
*/
/**service层切面 - 配置接入点,即为所要记录的action操作目录*/
private final String POINT_CUT = "execution(* com.wyq.springBoot.ctrl..*(..))";
@Pointcut(POINT_CUT)
private void pointcut(){}
@After("pointcut()")
public void doAfterAdvice(JoinPoint pjp) throws Throwable{
// 拦截的实体类,就是当前正在执行的controller
Object target = pjp.getTarget();
// 拦截的方法名称。当前正在执行的方法
String methodName = pjp.getSignature().getName();
// 拦截的放参数类型
Signature sig = pjp.getSignature();
MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
msig = (MethodSignature) sig;
Class[] parameterTypes = msig.getMethod().getParameterTypes();
Method method = target.getClass().getMethod(methodName, parameterTypes);
if (null != method) {
// 获取方法(此为自定义注解)
MyLog op = method.getAnnotation(MyLog.class);
if(op != null){
// 获取注解的modules 设为操作模块
System.out.println(op.module());
// 获取注解的methods 设为执行方法
System.out.println(op.method());
//NOTE!!--这里可操作:将得到的module、method用logService(自己定义)的方法存到数据库
}
}
}
}
解读:注意配置的有效包路径:POINT_CUT = "execution(* com.wyq.springBoot.ctrl..*(..))";可修改。
4.在配置的节点目录下的类的方法上添加@MyLog自定义注解
package com.wyq.springBoot.ctrl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wyq.springBoot.aop.MyLog;
import com.wyq.springBoot.domain.Teacher;
import com.wyq.springBoot.srv.TeacherSrv;
@RestController
@RequestMapping("/teacher")
public class TeacherCtrl {
@Autowired
private TeacherSrv teacherSrv;
@MyLog(module="老师模块", method="查询全部")
@RequestMapping("/all")
public List<Teacher> all(){
List<Teacher> ts = teacherSrv.getAll();
return ts;
}
}
解读:请求http://127.0.0.1:8080/teacher/all,代码进入controller对应方法,查询列表返回,随后代码运行入第3步中MyLogAction类的doAfterAdvice()方法。可断点调试