回顾SpringAOP的使用方式

一 概述

SpringAOP的实现主要有两种代理方式:

1.基于JDK的动态代理:是面向接口,实现具体的接口,形成代理对象,同时运用到反射机制。

2.基于CGLIB的动态代理:以继承的方式动态生成目标类的代理,基于ASM字节码库实现。

二 SpringAOP的具体实现方式

1. 通过XML配置方式实现

2. 通过注解的方式实现(目前主要的方式)

三 SpringAOP的主要注解

1. @Aspect:用来标注某个类为切面配置类

@Aspect
@Component
public class SecurityAspect {

    @Autowired
    AuthService authService;

    @Pointcut("@annotation(AdminOnly)")
    public void adminOnly() {

    }

    @Before("adminOnly()")
    public void checkAccess(){
        authService.checkAccess();
    }
}

2. @Pointcut:可以理解为切入点,指定我们要织入代码的具体位置。

四 SpringAOP中的Pointcut expression(切面表达式)

切面表达式主要由三部分组成:

1. 指示器(designators):指定方式匹配目标Java方法的实例。

  • 匹配方法:execution()通过通配符执行流将想要拦截的方法直接筛选出来(重点)。
  1. modifier-pattern?(修饰符pattern,可省略
  2. ret-type-pattern (返回值pattern)
  3. declaring-type-pattern? (包名pattern,可省略)
  4. name-pattern(param-pattern) (方法名,方法参数pattern)
  5. throws-pattren? (匹配方法异常的pattern,可省略)
  • 匹配注解:@target(),@args(),@within(),@annotation()可以筛选出有指定注解的方法。
    //匹配方法标注有AdminOnly的注解的方法
    @Pointcut("@annotation(com.zero.springaop.annotation.AdminOnly)")
    public void adminOnly() {

    }

    //匹配方法标注有NeedSecureed注解的类中方法,要求annotation的RetentionPolicy级别为ClASS
    @Pointcut("@within(com.zero.springaop.annotation.NeedSecured)")
    public void secured(){

    }

    //匹配标注有Repository注解的类中方法,要求annotation的RetentionPolicy级别为RUNTIME
    @Pointcut("@target(org.springframework.stereotype.Repository)")
    public void target(){
        
    }
    
    //匹配传入的参数类标注有Repositroy注解的方法
    @Pointcut("@args(org.springframework.stereotype.Repository)")
    public void args(){
        
    }

//注意@within和@target注解在Spring环境中是一样的,而不在Spring环境中前者注解的RetentionPolicy为CLASS,后者的RetentionPolicy则是RUNTIME
  • 匹配包/类型:within()。
    //匹配ProductService类中的所有方法
    @Pointcut("within(com.zero.springaop.service.ProductService)")
    public void mathType(){

    };
    
    //匹配com.zero包及其子包中所有类的方法
    @Pointcut("within(com.zero..*)")
    public void mathPackage(){
        
    }
  • 匹配对象:this(),bean(),target()。
    //匹配AOP对象的目标对象为指定类型的方法,及UserServiceImpl的aop代理对象的方法
    @Pointcut("this(com.zero.springaop.service.impl.UserServiceImpl)")
    public void thisInstance(){
        
    }
    
    //匹配实现UserService接口的目标对象(而不是AOP代理后的对象)的方法,这里即UserServiceImpl的方法
    @Pointcut("target(com.zero.springaop.service.UserService)")
    public void targetInstance(){
        
    }
    
    //匹配所有以Service结尾的bean中的方法
    @Pointcut("bean(*Service)")
    public void beanInstance(){
        
    }

//对于this和target的区别是this可以拦截动态生成的方法,而target则拦截不了
  • 匹配参数:args()。
    //匹配任何以get开头且只有一个类型为Long参数的方法
    @Pointcut("execution(* *..get*(Long))")
    public void argsInstance(){
        
    }
    
    //匹配任何另有一个Long参数的方法
    @Pointcut("args(Long)")
    public void argsInstanceL(){
        
    }
    
    //匹配任何以get开头的而且第一个参数为Long型的方法
    @Pointcut("execution(* *..get*(Long,..))")
    public void argsInstances() {
        
    }
    
    //匹配第一个参数为Long型的方法
    @Pointcut("args(Long,..)")
    public void argsInstanced(){
        
    }

2. 通配符 (wildcards):对于比较多了匹配实例,为了避免一一列举,我们可以使用通配符来完成。

  • * 用于匹配任意数量的字符
  • + 用于匹配指定类及其子类(类似于java泛型中的extends,同时匹配基类与所有集成基类的子类)
  • .. 一般用于匹配任意数量的子包或参数

3. 运算符(operators):进行逻辑上的或与非运算。如:||(或),&&(与),!(非)。

扫描二维码关注公众号,回复: 12552986 查看本文章

猜你喜欢

转载自blog.csdn.net/calm_encode/article/details/113587321
今日推荐