表达式格式:execution(方法修饰符 返回类型 类.方法(参数类型..))
-
execution(public * *(..))
- 匹配任意public类型的方法
-
execution(* xx*(..))
- 匹配"xx"开头的任意方法
-
execution(* xxx.xxx.service.XXXService.*(..))
- 匹配XXXService类下的所有方法
-
execution(* xxx.xxx.service.*.*(..))
- 匹配service包下的类和方法
-
execution(* xxx.xxx.service..*.*(..))
- 匹配service包及子包下的类和方法
-
within(xxx.xxx.service.*)
- 匹配service包下的类, 必须是包路径, 不能包含类名信息
-
within(xxx.xxx.service..*)
- 匹配service包及子包下的类, 必须是包路径, 不能包含类名信息
-
this(xxx.xxx.service.XXXService)
- 代理对象的类型匹配this指定的类型
* JDK生成的动态代理类:实现接口为目标类的接口, 继承Proxy类
* CGLIB生成的动态代理类:实现接口为目标类的接口, 继承目标类
* 当采用JDK动态代理时,代理类和目标类没有直接关系, 二者只是实现相同的接口, 如果this表达式指定的是目标类时无法匹配命中
-
target(xxx.xxx.service.XXXService)
- 目标对象类型匹配target指定的类型
* this作用于代理对象,target作用于目标对象
* this表示目标对象被代理之后生成的代理对象和指定的类型匹配会被拦截,匹配的是代理对象
* target表示目标对象和指定的类型匹配会被拦截,匹配的是目标对象
-
args(*, int)
- 匹配参数个数为2的方法,第一个任意类型,第二个int类型
-
@target(Service)
- 匹配目标对象的类型被@Service注解
-
@within(Service)
- 匹配被调目标方法所属的类被@Service注解
* 被调目标方法被子类重新,那么方法就属于子类,@Service在父类上,子类上没有注解,不会被拦截
* 被调目标方法未被子类重新,那么方法就属于父类,@Service在父类上,父类上有注解,会被拦截
* @target(注解A):判断被调用的目标对象中是否声明了注解A,如果有,会被拦截
* @within(注解A): 判断被调用的方法所属的类中是否声明了注解A,如果有,会被拦截
* @target关注的是被调用的对象,@within关注的是调用的方法所在的类
-
@annotation(Transactional)
- 匹配被@Transactional注解的方法
-
@args(Service)
- 匹配参数个数为1的方法,且第一个参数所属的类型上有注解@Service(注意不是参数上的注解,而是参数类型上的注解)
测试代码:
package org.spring.aop.expression;
public class AspectJExpressionTest {
public static void main(String[] args) {
testExecution();
System.out.println("\n");
testWithin();
System.out.println("\n");
testThis();
System.out.println("\n");
testTarget();
System.out.println("\n");
testArgs();
System.out.println("\n");
testAnnotationTarget();
System.out.println("\n");
testAnnotationWithin();
System.out.println("\n");
testAnnotation();
System.out.println("\n");
testAnnotationArgs();
}
public static void testExecution() {
System.out.println("------------test execution()------------");
String expression = "execution(* org.spring.aop.expression.service.ServiceImpl.*(..))";
Advisor advisor = buildAdvisor(expression);
ProxyFactory proxyFactory = new ProxyFactory(new ServiceImpl());
proxyFactory.addAdvisors(advisor);
IService service = (IService) proxyFactory.getProxy();
service.say("execution()");
}
public static void testWithin() {
System.out.println("------------test within()------------");
String expression = "within(org.spring.aop.expression.service.*)";
Advisor advisor = buildAdvisor(expression);
ProxyFactory proxyFactory = new ProxyFactory(new ServiceImpl());
proxyFactory.addAdvisors(advisor);
IService service = (IService) proxyFactory.getProxy();
service.say("within()");
}
public static void testThis() {
System.out.println("------------test this()------------");
String expression = "this(org.spring.aop.expression.service.ServiceImpl)";
Advisor advisor = buildAdvisor(expression);
ProxyFactory proxyFactory = new ProxyFactory(new ServiceImpl());
//采用JDK动态代理
proxyFactory.setProxyTargetClass(false);
proxyFactory.addAdvisors(ExposeInvocationInterceptor.ADVISOR, advisor);
IService service = (IService) proxyFactory.getProxy();
service.say("this()");
proxyFactory = new ProxyFactory(new ServiceImpl());
//采用CGLIB动态代理
proxyFactory.setProxyTargetClass(true);
proxyFactory.addAdvisors(ExposeInvocationInterceptor.ADVISOR, advisor);
service = (IService) proxyFactory.getProxy();
service.say("this()");
}
public static void testTarget() {
System.out.println("------------test target()------------");
String expression = "target(org.spring.aop.expression.service.ServiceImpl)";
Advisor advisor = buildAdvisor(expression);
ProxyFactory proxyFactory = new ProxyFactory(new ServiceImpl());
proxyFactory.addAdvisors(ExposeInvocationInterceptor.ADVISOR, advisor);
IService service = (IService) proxyFactory.getProxy();
service.say("target()");
}
public static void testArgs() {
System.out.println("------------test args()------------");
String expression = "args(*, int)";
Advisor advisor = buildAdvisor(expression);
ProxyFactory proxyFactory = new ProxyFactory(new ServiceImpl());
proxyFactory.addAdvisors(advisor);
IService service = (IService) proxyFactory.getProxy();
service.say("args()");
service.say("args()", 5);
}
public static void testAnnotationTarget() {
System.out.println("------------test @target()------------");
String expression = "@target(org.springframework.stereotype.Service)";
Advisor advisor = buildAdvisor(expression);
ProxyFactory proxyFactory = new ProxyFactory(new AnnotationService());
proxyFactory.addAdvisors(ExposeInvocationInterceptor.ADVISOR, advisor);
AnnotationService service = (AnnotationService) proxyFactory.getProxy();
service.say();
System.out.println();
proxyFactory = new ProxyFactory(new AnnotationServiceImpl());
proxyFactory.addAdvisors(ExposeInvocationInterceptor.ADVISOR, advisor);
service = (AnnotationService) proxyFactory.getProxy();
service.say();
}
public static void testAnnotationWithin() {
System.out.println("------------test @within()------------");
String expression = "@within(org.springframework.stereotype.Service)";
Advisor advisor = buildAdvisor(expression);
ProxyFactory proxyFactory = new ProxyFactory(new AnnotationServiceImpl());
proxyFactory.addAdvisors(advisor);
AnnotationServiceImpl service = (AnnotationServiceImpl) proxyFactory.getProxy();
//AnnotationServiceImpl重写了AnnotationService的say方法,方法属于AnnotationServiceImpl但是AnnotationServiceImpl上没有@Service注解
//不拦截
service.say();
//AnnotationServiceImpl未重写AnnotationService的hello方法,方法属于AnnotationService,AnnotationService上有@Service注解
//拦截
service.hello();
}
public static void testAnnotation() {
System.out.println("------------test @annotation()------------");
String expression = "@annotation(org.springframework.transaction.annotation.Transactional)";
Advisor advisor = buildAdvisor(expression);
ProxyFactory proxyFactory = new ProxyFactory(new AnnotationServiceImpl());
proxyFactory.addAdvisors(advisor);
AnnotationServiceImpl service = (AnnotationServiceImpl) proxyFactory.getProxy();
service.say();
System.out.println();
service.doSomthing();
}
public static void testAnnotationArgs() {
System.out.println("------------test @args()------------");
String expression = "@args(org.springframework.stereotype.Service)";
Advisor advisor = buildAdvisor(expression);
ProxyFactory proxyFactory = new ProxyFactory(new AnnotationServiceImpl());
proxyFactory.addAdvisors(advisor);
AnnotationServiceImpl service = (AnnotationServiceImpl) proxyFactory.getProxy();
service.say();
AnnotationService annotationService = new AnnotationService();
service.doSomthing(annotationService);
}
public static Advisor buildAdvisor(String expression) {
//创建pointcut
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(expression);
System.out.println("------------MethodMatcher.isRuntime()=" + pointcut.isRuntime() + "------------");
//创建advice
LogAdvice advice = new LogAdvice();
//创建advisor
Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
return advisor;
}
}
package org.spring.aop.expression.service;
public interface IService {
default void say(String name) {}
default void say(String name, int age) {}
}
package org.spring.aop.expression.service;
public class ServiceImpl implements IService {
@Override
public void say(String name) {
System.out.println("I am " + name + "!!");
}
@Override
public void say(String name, int age) {
System.out.println("I am " + name + "!! " + age + " years old");
}
}
package org.spring.aop.expression.service;
import org.springframework.stereotype.Service;
@Service
public class AnnotationService {
public void say() {
System.out.println("I am AnnotationService.say()!!");
}
public void hello() {
System.out.println("I am AnnotationService.hello()!!");
}
public void doSomthing() {
System.out.println("I am AnnotationService.doSomthing()!!");
}
}
package org.spring.aop.expression.service;
import org.springframework.transaction.annotation.Transactional;
public class AnnotationServiceImpl extends AnnotationService {
@Transactional
public void say() {
System.out.println("I am AnnotationServiceImpl.say()!!");
}
public void doSomthing(AnnotationService annotationService) {
System.out.println("I am AnnotationServiceImpl.(@Param(\"name\") String name)!!");
}
}
package org.spring.aop.expression.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class LogAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("===============log record start==============");
Object object = methodInvocation.proceed();
System.out.println("===============log record end================");
return object;
}
}