Spring AOP的多种实现方式

 

Spring AOP有多种实现方式,基于Spring xml配置的,基于注解配置的,基于切点函数配置等等,还有其他的实现方式,这里主要记录提到的三种方式

一.基于xml配置的AOP

  1. 首先定义一个AOP的通知类,包含方法执行前的方法,方法执行后的方法,还有环绕等方法;如下:
/**
 * @author eleven
 * @date 2018/11/4
 * @description
 */
@Slf4j
public class GlobalAdvices {

    public void before(){
        log.warn(">>>>>前置通知:before");
    }

    public void after(){
        log.info(">>>>>后置通知:after");
    }
}

     2.将通知类交给spring容器管理,并且配置AOP,如下:

 

//定义AOP切面

//定义AOP切入点

//前置通知方法

//后置通知方法

      3.这样基于xml配置的AOP就算完成,所有调用service方法都会被切到;

二.基于注解配置的AOP

1.定义一个通知类,如下:

/**

* @author eleven

* @date 2018/11/4

* @description AOP

*/

@Slf4j

@Aspect

public class RequestAdvice {

/**

* 定义一个通用的切点,解决切点复用问题

*/

@Pointcut("execution(* cn.llf.framework.services..*.*(..))")

public void pointcut(){}

 

/**

* 直接在通知方法定义切点

* @param joinPoint

*/

@Before("pointcut()")

public void before(JoinPoint joinPoint){

 

log.warn(">>>>>前置通知");

}

 

/**

* 引用定义好的切点

* @param joinPoint

*/

@After("pointcut()")

public void after(JoinPoint joinPoint){

log.warn(">>>>>后置通知");

}

}

2.如 注释所说,可以定义先定义一个切入点,接着之后的各种通知就可以复用一个切入点,避免切入点代码重复;

3.对应的前制通知使用@before声明为前制通知,用@after声明为后置通知;

4.类头需要使用@asperct申明该类为切面,这样spring容器才能识别;

5.接着将该切面类收进spring容器管理,需要在xml配置,如下:

6.最后还需要在spring中配置启动@asperct注解的支持,aspect注解就是包括上面的@asperct,@before等注解,配置如下:

7.上述就是基于注解的AOP的实现方式,配置完成,所有的service层的方法都已经纳入到AOP的切面范围了;

8.JoinPoint解释:进入切面之后,可以获取到拦截到的方法的一些参数信息;注意区别Joinpoint类;仅差一个P大小写问题,却关系到AOP能否启动

三.基于切点函数配置的AOP

  1. 基于切点函数的AOP,其切点函数包括9种的函数,

@AspectJ使用AspectJ专门的切点表达式描述切面,Spring所支持的AspectJ表达式可分为四类:

  • 方法切点函数:通过描述目标类方法信息定义连接点。
  • 方法参数切点函数:通过描述目标类方法入参信息定义连接点。
  • 目标类切点函数:通过描述目标类类型信息定义连接点。
  • 代理类切点函数:通过描述代理类信息定义连接点。

常见的AspectJ表达式函数:

  • execution():满足匹配模式字符串的所有目标类方法的连接点
  • @annotation():任何标注了指定注解的目标方法链接点
  • args():目标类方法运行时参数的类型指定连接点
  • @args():目标类方法参数中是否有指定特定注解的连接点
  • within():匹配指定的包的所有连接点
  • target():匹配指定目标类的所有方法
  • @within():匹配目标对象拥有指定注解的类的所有方法
  • @target():匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解
  • this():匹配当前AOP代理对象类型的所有执行方法

 

     2.上述9种切点函数种,execution函数在前面的两种实现方式已经提及,这里另外主要记录@annotation方式的切点函数 

     3.首先需要定义在方法上要使用的注解,如下:

/**

* @author eleven

* @date 2018/11/4

* @description AOP

*/

@Documented

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface MethodInvocationStatistic {

/**

* 方法作用

* @return

*/

String methodName() default "";

/**

* 方法类型

*/

int type() default 1;

}

    4.其次在需要AOP的方法上使用该注解:

@Override

@MethodInvocationStatistic(methodName = "获取用户分页数据")

public List list(UserInfoPO query) {

List list = dao.list(query);

return list;

}

   5.定义AOP通知类,其中的通知方法不在使用execution函数,而是使用这里提到的annotation函数,如下:

/**

* @author eleven

* @date 2018/11/4

* @description AOP

*/

@Slf4j

@Aspect

public class RequestAdvice {

/**

* 切面范围为有使用 {@link MethodInvocationStatistic}的方法

* @param joinPoint

*/

@Before("@annotation(cn.llf.framework.annotation.MethodInvocationStatistic)")

public void actionRecord(JoinPoint joinPoint){

Signature signature = joinPoint.getSignature();

log.info("标有注解的【{}】的方法被AOP切面切到,方法签名:【{}】", MethodInvocationStatistic.class.getName(),signature);

}

}

    6.同样将该通知类交给spring容器管理,如下:

     7.最后还是启动aspect注解的支持

 

 

你可能感兴趣的:(spring)