1.springboot环境下导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.自定义注解
@Target(value = {ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})//该注解可以放在方法上,属性上,类上 @Retention(RetentionPolicy.RUNTIME)//运行环境下 public @interface MyLog { String value() default ""; }
3.编写简单的controller
@Controller
public class UserController {
@GetMapping("/listUser")
@ResponseBody
@MyLog(value = "日志记录查看了用户权限")//自定义注解
public String listUser () {
return "查看用户权限";
}
}
4.编写切面类
@Aspect @Component public class MyAspec { public MyAspec(){ } //切点扫描某个包下某个加了注解的方法,如果只加注解类就会全部扫描 @Pointcut("execution(* com.qj.shiro.controller.*.*(..)) && @annotation(com.qj.shiro.annotation.MyLog)") public void targetMyAspec(){ } //后置通知(可不写),其他通知省略 @After("targetMyAspec()") public void afterlogin(){ System.out.println("after。。。。"); }
//环绕通知 @Around("targetMyAspec()") public Object Interceptor(ProceedingJoinPoint pjp){ Object result = null; Class<?> aClass = pjp.getTarget().getClass();//获得所在切点的该类的class对象,也就是UserController这个类的对象 String name = pjp.getSignature().getName();//获取该切点所在方法的名称,也就是listUser try { Method method = aClass.getMethod(name);//通过反射获得该方法 MyLog annotation = method.getAnnotation(MyLog.class);//获得该注解 System.out.println(annotation.value());//获得自定义注解上面的值 } catch (NoSuchMethodException e) { e.printStackTrace(); } try { result =pjp.proceed();//执行该方法 } catch (Throwable e) { e.printStackTrace(); } return result; } }
5.最终执行
在idea控制台打印如下语句: