Aspect 切入点 @Pointcut 语法详解

分类pointcuts 遵循特定的语法用于捕获每一个种类的可使用连接点。

主要的种类:
方法执行:execution(MethodSignature)
方法调用:call(MethodSignature)
构造器执行:execution(ConstructorSignature)
构造器调用:call(ConstructorSignature)
类初始化:staticinitialization(TypeSignature)
属性读操作:get(FieldSignature)
属性写操作:set(FieldSignature)
例外处理执行:handler(TypeSignature)
对象初始化:initialization(ConstructorSignature)
对象预先初始化:preinitialization(ConstructorSignature)

切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示符如下:

execution:用于匹配方法执行的连接点;
within:用于匹配指定类型内的方法执行;
this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;
target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;
@within:用于匹配所以持有指定注解类型内的方法;
@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;
@args:用于匹配当前执行的方法传入的参数持有指定注解的执行;
@annotation:用于匹配当前执行方法持有指定注解的方法;
bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;
reference pointcut:表示引用其他命名切入点,只有@ApectJ风格支持,Schema风格不支持。

AspectJ类型匹配的通配符

*:匹配任何数量字符;
…:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
+:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。

举例说明

任意公共方法的执行:
execution(public * *(..))

任何一个以“set”开始的方法的执行:
execution(* set*(..))

AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))

定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(..))

定义在service包和所有子包里的任意类的任意方法的执行:
execution(* com.xyz.service..*.*(..))

定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:
execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")
***> 最靠近(..)的为方法名,靠近.*(..))的为类名或者接口名,如上例的JoinPointObjP2.*(..))
 
pointcutexp包里的任意类.
within(com.test.spring.aop.pointcutexp.*)

pointcutexp包和所有子包里的任意类.
within(com.test.spring.aop.pointcutexp..*)

实现了Intf接口的所有类,如果Intf不是接口,限定Intf单个类.
this(com.test.spring.aop.pointcutexp.Intf)
***> 当一个实现了接口的类被AOP的时候,用getBean方法必须cast为接口类型,不能为该类的类型.
 
带有@Transactional标注的所有类的任意方法.
@within(org.springframework.transaction.annotation.Transactional)
@target(org.springframework.transaction.annotation.Transactional)

带有@Transactional标注的任意方法.
@annotation(org.springframework.transaction.annotation.Transactional)
***> @within和@target针对类的注解,@annotation是针对方法的注解
 
参数带有@Transactional标注的方法.
@args(org.springframework.transaction.annotation.Transactional)

范例

controller

@myLog
@RestController
@RequestMapping("/test")
public class TestController {

    @Resource
    IMqProducerService mqProducerService;

    @GetMapping("/t1")
    public String t1() {
        return mqProducerService.test();
    }
}

注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface myLog {
    String topic() default "";
}

controller包下面的所有类的方法切面

@Aspect
@Component
public class myLogAspect1 {

    @Pointcut("execution(public * org.demo.activemq.controller.*.*(..))")
    public void pointCut1() {}

    @After("pointCut1()")
    public void runAfter(JoinPoint joinPoint) {
        System.out.println("执行方法之后执行。。。。。");
    }
}

mylog在类上的切面

@Aspect
@Component
public class myLogAspect2 {

    @Pointcut("@within(org.demo.activemq.mylog.myLog)")
    public void pointCut2() {
    }

    @Around("pointCut2()")
    public Object Around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("AnnotationAspectTest Around start ");

        //去调用被拦截的方法
        Object proceed = point.proceed();

        return proceed;
    }

    //获取注解
    public myLog getAnnotation(ProceedingJoinPoint point) {
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null) {
            return method.getAnnotation(myLog.class);
        }

        return null;
    }

}

你可能感兴趣的:(java,数据库,前端)