SpringBoot——AOP注解式拦截与⽅法规则拦截
  AspectJ是⼀个⾯向切⾯的框架,它扩展了Java语⾔。AspectJ定义了AOP语法,所以它有⼀个专门的编译器⽤来⽣成遵守Java字节编码规范的Class⽂件。
  SpringBoot中AOP的使⽤⽅式主要有两种:注解式拦截与⽅法规则拦截,具体使⽤如下⽂所⽰。
⼀、创建⼀个简单springboot 2.03项⽬,添加aop依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
 此依赖已包含AspectJ相关依赖包。
⼆、编写拦截规则的注解
bitor.aop.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
String name();
}
注解说明:元注解是指注解的注解,包括@Retention @Target @Document @Inherited四种。
1.@Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE)  //注解仅存在于源码中,在class字节码⽂件中不包含
@Retention(RetentionPolicy.CLASS)    // 默认的保留策略,注解会在class字节码⽂件中存在,但运⾏时⽆法获得,
@Retention(RetentionPolicy.RUNTIME)  // 注解会在class字节码⽂件中存在,在运⾏时可以通过反射获取到
  ⾸先要明确⽣命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作⽤的地⽅后者⼀定也能作⽤。⼀般如果需要在运⾏时去动态获取注解信息,那只能⽤ RUNTIME 注解;如果要在编译时进⾏⼀些预处理操作,⽐如⽣成⼀些辅助代码(如 ButterKnife),就⽤ CLASS 注解;如果只是做⼀些检查性的操作,⽐如 @Override 和 @SuppressWarnings,则可选⽤ SOURCE 注解。
2.@Target:定义注解的作⽤⽬标
 源码为:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
@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) ///包
3.@Document:说明该注解将被包含在javadoc中
4.@Inherited:说明⼦类可以继承⽗类中的该注解
三、编写使⽤注解的被拦截类
bitor.aop.service;
bitor.aop.annotation.Action;
import org.springframework.stereotype.Service;
@Service
public class DemoAnnotationService {
@Action(name = "注解式拦截的add操作")
public void add(){}
}
四、编写使⽤⽅法规则被拦截类
bitor.aop.service;
import org.springframework.stereotype.Service;
@Service
public class DemoMethodService {
public void add(){}
}
五、编写切⾯
bitor.aop.aspect;
bitor.aop.annotation.Action;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.flect.MethodSignature;
import org.springframework.stereotype.Component;
import flect.Method;
@Aspect
@Component
public class LogAspect {
@Pointcut("@bitor.aop.annotation.Action)")
public void annotationPoinCut(){}
@After("annotationPoinCut()")
public void after(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) Signature();
Method method = Method();
Action action = Annotation(Action.class);
System.out.println("注解式拦截 "+action.name());
}
@Before("execution(* bitor.aop.service.DemoMethodService.*(..))")
public void before(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) Signature();
Method method = Method();
System.out.println("⽅法规则式拦截,"+Name());
}
}
AOP注解说明:
@Aspect 定义切⾯:切⾯由切点和增强(引介)组成(可以包含多个切点和多个增强),它既包括了横切逻辑的定义,也包括了连接点的定义,SpringAOP就是负责实施切⾯的框架,它将切⾯所定义的横切逻辑织⼊到切⾯所指定的链接点中。
@Pointcut 定义切点:切点是⼀组连接点的集合。AOP通过“切点”定位特定的连接点。通过数据库查询的概念来理解切点和连接点的关系再适合不过了:连接点相当于数据库中的记录,⽽切点相当于查询条件。
@Before :在⽬标⽅法被调⽤之前做增强处理,@Before只需要指定切⼊点表达式即可。
@AfterReturning :在⽬标⽅法正常完成后做增强,@AfterReturning除了指定切⼊点表达式后,还可以指定⼀个返回值形参名
returning,代表⽬标⽅法的返回值。
@Afterthrowing:主要⽤来处理程序中未处理的异常,@AfterThrowing除了指定切⼊点表达式后,还可以指定⼀个throwing的返回值形参名,可以通过该形参名来访问⽬标⽅法中所抛出的异常对象。
@After:在⽬标⽅法完成之后做增强,⽆论⽬标⽅法时候成功完成。@After可以指定⼀个切⼊点表达式。
@Around:环绕通知,在⽬标⽅法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,⽇志等都是环绕通知,注意编程中核⼼是⼀个ProceedingJoinPoint。
六、运⾏
public class main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopApplication.class);
DemoAnnotationService demoAnnotationService = Bean(DemoAnnotationService.class);
springboot框架的作用
DemoMethodService demoMethodService = Bean(DemoMethodService.class);
demoAnnotationService.add();
demoMethodService.add();
}
}
AopApplication.class为本项⽬的启动类。
运⾏结果如下:
注解式拦截注解式拦截的add操作
⽅法规则式拦截,add
注:摘抄⾃《JavaEE开发的颠覆者SpringBoot 实战》,根据springboot 2.0.3做些许修改,省略⼀些配置项。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。