AOP一些理论和spring boot环境搭建免去,直接aop实现(LZ也是自己跟着官网学spring boot,原理概念性的东西,也是看官网和别人的分享,这里不敢说多了,会出错)
maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
LZ采用2种方式实现aop,着重讲解自定义注解模式(自我感觉方便很多)
普通模式
首先看一下 controller代码
@RestController
public class JpaController {
@GetMapping("/hello")
public String hello(){
System.out.println("JpaController.hello 11111");
return "public String hello()";
}
}
在接着定义一个HttpAspect,采取的是环绕通知,定义 @Pointcut中的语法,自己官网看,这里的意思拦截JpaController中所有方法
@Aspect
@Component
public class HttpAspect {
@Pointcut("execution(public * com.lf.web.JpaController.*(..))")
public void log(){
}
@Around("log()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("Around start..... 00000");
try {
Object result = proceedingJoinPoint.proceed();
System.out.println("Around end 22222:" + result);
return result;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
}
好了,其他的省略,启动程序,访问http://127.0.0.1:7777/hello,控制台打印的顺序如下图
注意的是around方法里要执行proceedingJoinPoint.proceed()才会到controller方法里面去,在把结果返回出来
注解模式
1.定义一个注解
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AopAnnotationTest {
}
<这里复制别人的> LZ上面定义了2个@Target,这里效果就是此注解放在类上面,方法上面都可以,@Retention是必须加的注解
RetentionPolicy.RUNTIME // 保留至运行时
RetentionPolicy.SOURCE //编译器忽略
RetentionPolicy.CLASS //注解将会被保留在Class文件中,但在运行时并不会被VM保留。这是默认行为,所有没有用Retention注解的注解,都会采用这种策略
@Target(ElementType.TYPE) // 接口、类、枚举、注解
@Target(ElementType.FIELD) // 字段、枚举的常量
@Target(ElementType.METHOD) // 方法
@Target(ElementType.PARAMETER) // 方法参数
@Target(ElementType.CONSTRUCTOR) // 构造函数
@Target(ElementType.LOCAL_VARIABLE) // 局部变量
@Target(ElementType.ANNOTATION_TYPE) // 注解
@Target(ElementType.PACKAGE) / // 包
2.JpaController
@RestController
@AopAnnotationTest
public class JpaController {
@GetMapping("/hello")
public String hello(){
System.out.println("JpaController.hello 11111");
return "public String hello()";
}
}
3.HttpAspect
@within 让定义在类上面的注解生效
@annotation 方法上面
@Aspect
@Component
public class HttpAspect {
@Pointcut("@within(aopAnnotationTest) || @annotation(aopAnnotationTest)")
public void log2(AopAnnotationTest aopAnnotationTest){
}
@Around("log2(aopAnnotationTest)")
public Object around(ProceedingJoinPoint proceedingJoinPoint,AopAnnotationTest aopAnnotationTest) {
System.out.println("Around start..... 00000");
try {
Object result = proceedingJoinPoint.proceed();
System.out.println("Around end 22222:" + result);
return result;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
启动程序,控制台打印如下
好了,注解方式这样配置好了之后,想要把哪个方法/类 aop一下,直接加入该注解即可
问题!!!!!
LZ采用注解方法,把注解加在接口上面没有生效,放在实现上面是可以的,放在接口上面LZ采用的普通方式