格式:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
括号中各个pattern分别表示:
现在来看看几个例子:
1)execution(* *(..)) //表示匹配所有方法 2)execution(public * com. savage.service.UserService.*(..)) //表示匹配com.savage.server.UserService中所有的公有方法 3)execution(* com.savage.server..*.*(..)) //表示匹配com.savage.server包及其子包下的所有方法
在Spring 2.0中,Pointcut的定义包括两个部分:Pointcut表示式(expression)和Pointcut签名(signature)
//Pointcut表示式
@Pointcut("execution(* com.savage.aop.MessageSender.*(..))")
//Point签名
private void log(){}
然后要使用所定义的Pointcut时,可以指定Pointcut签名 如下:
@Before("log()")
这种使用方式等同于以下方式,直接定义execution表达式使用
@Before("execution(* com.savage.aop.MessageSender.*(..))")
Pointcut定义时,还可以使用&&、||、! 这三个运算
@Pointcut("execution(* com.savage.aop.MessageSender.*(..))")
private void logSender(){}
@Pointcut("execution(* com.savage.aop.MessageReceiver.*(..))")
private void logReceiver(){}
@Pointcut("logSender() || logReceiver()")
private void logMessage(){}
这个例子中,logMessage()将匹配任何MessageSender和MessageReceiver中的任何方法。
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是针对方法的注解,为自定义注解
如:
/** * 选取切入点为自定义注解 */
@Pointcut("@annotation(com.honeywen.credit.annotation.PermissionCheck)")
① 在类上使用 @Component 注解 把切面类加入到IOC容器中
② 在类上使用 @Aspect 注解 使之成为切面类
用@Aspect注解方式来实现前置通知、返回通知、后置通知、异常通知、环绕通知。
package com.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @author wanjiadong
* @description
* @date Create in 15:09 2019/1/3
*/
@Aspect
@Component
public class AspectTest {
@Pointcut("execution(* com.service..*.*(..))")
public void pointcut(){
}
@Pointcut("@annotation(Override) || @within(Override)")
public void pointcutAnnotation(){}
/**
* 前置通知:目标方法执行之前执行以下方法体的内容
*
* @param joinPoint
*/
@Before("pointcut()")
public void before(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
System.out.println(joinPoint.getArgs()[0].getClass());
System.out.println(joinPoint.getArgs()[0].getClass().getGenericSuperclass());
System.out.println(joinPoint.getArgs()[0].getClass().getSuperclass());
System.out.println(joinPoint.getArgs()[0].getClass().getSuperclass().getSuperclass());
System.out.println("【前置通知】the method 【" + methodName + "】 begins with " + Arrays.asList(joinPoint.getArgs()));
}
/**
* 环绕通知:目标方法执行前后分别执行一些代码,发生异常的时候执行另外一些代码
*
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
String methodName = proceedingJoinPoint.getSignature().getName();
Object result = null;
//目标参数
Object args = proceedingJoinPoint.getArgs();
//获取方法
Method method = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod();
//获取方法上的注解
Override override = method.getAnnotation(Override.class);
try {
System.out.println("【环绕通知中的--->前置通知】:the method 【" + methodName + "】 begins with " + Arrays.asList(proceedingJoinPoint.getArgs()));
//执行目标方法
result = proceedingJoinPoint.proceed();
System.out.println("【环绕通知中的--->返回通知】:the method 【" + methodName + "】 ends with " + result);
} catch (Throwable e) {
System.out.println("【环绕通知中的--->异常通知】:the method 【" + methodName + "】 occurs exception " + e);
}
System.out.println("【环绕通知中的--->后置通知】:-----------------end.----------------------");
return result;
}
/**
* 返回通知:目标方法正常执行完毕时执行以下代码
*
* @param joinPoint
* @param result
*/
@AfterReturning(value = "pointcut()", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) {
result = "hahah";
String methodName = joinPoint.getSignature().getName();
System.out.println("【返回通知】the method 【" + methodName + "】 ends with 【" + result + "】");
}
/**
* 异常通知:目标方法发生异常的时候执行以下代码
*
* @param joinPoint
* @param e
*/
@AfterThrowing(value = "pointcut()", throwing = "e")
public void throwing(JoinPoint joinPoint, Exception e) {
e = new NullPointerException();
String methodName = joinPoint.getSignature().getName();
System.out.println("【异常通知】the method 【" + methodName + "】 occurs exception: " + e);
}
/**
* 后置通知:目标方法执行之后执行以下方法体的内容,不管是否发生异常。
*
* @param joinPoint
*/
@After("pointcut()")
public void after(JoinPoint joinPoint) {
System.out.println("【后置通知】this is a afterMethod advice...");
}
}