Spring AOP有多种实现方式,基于Spring xml配置的,基于注解配置的,基于切点函数配置等等,还有其他的实现方式,这里主要记录提到的三种方式
/** * @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,如下:
3.这样基于xml配置的AOP就算完成,所有调用service方法都会被切到;
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能否启动
@AspectJ使用AspectJ专门的切点表达式描述切面,Spring所支持的AspectJ表达式可分为四类:
常见的AspectJ表达式函数:
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
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注解的支持