Aspect 是如何解析表达式?或者说是如何通过表达式知道哪个对象需要被创建代理

Spring 在解析 @Aspect 表达式其实用到的就是Aspect 包里面的API 。

第一个对象 PointcutParser 顾名思义 切点解析器

第二个对象 PointcutExpression 切点表达式对象

如何去解析并命中对象呢

1.构建 PointcutParser Aspect API

PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(PointcutParser.getAllSupportedPointcutPrimitives(),this.getClass().getClassLoader());

2.通过 PointcutParser 和 表达式去 构建 PointcutExpression 对象

	private PointcutExpression pointcutExpression;

	public AspectJExpressionPointCut(String expression){
		this.pointcutExpression = pointcutParser.parsePointcutExpression(expression);
	}

匹配对象一共分为两步,就是两次匹配

	public boolean oneMatches(Class<?> clazz){
		return pointcutExpression.couldMatchJoinPointsInType(clazz);
	}

	public boolean twoMatches(Method method){
		ShadowMatch shadowMatch = pointcutExpression.matchesMethodExecution(method);
		return shadowMatch.alwaysMatches();
	}

全部代码

public class AspectJExpressionPointCut {

	private PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(
			PointcutParser.getAllSupportedPointcutPrimitives(),this.getClass().getClassLoader());

	private PointcutExpression pointcutExpression;

	public AspectJExpressionPointCut(String expression){
		this.pointcutExpression = pointcutParser.parsePointcutExpression(expression);
	}

	public boolean oneMatches(Class<?> clazz){
		return pointcutExpression.couldMatchJoinPointsInType(clazz);
	}

	public boolean twoMatches(Method method){
		ShadowMatch shadowMatch = pointcutExpression.matchesMethodExecution(method);
		return shadowMatch.alwaysMatches();
	}
}

开始测试 创建AOP

@Component
@Aspect
public class AopService {

	@Pointcut("execution(public * org.springframework.waf.UserService.uService01(..))")
	public void pointCut01(){}

	@Pointcut("execution(public * org.springframework.waf.OrderService.*(..))")
	public void pointCut02(){}

	@Before("pointCut01()")
	public void beforeMethod01(){
		System.out.println("beforeMethod01");
	}

	@After("pointCut01()")
	public void afterMethod01(){
		System.out.println("afterMethod01");
	}

	@Around("pointCut01()")
	public void aroundMethod01(){
		System.out.println("aroundMethod01");
	}

	@Before("pointCut02()")
	public void beforeMethod02(){
		System.out.println("beforeMethod02");
	}

	@After("pointCut02()")
	public void afterMethod02(){
		System.out.println("afterMethod02");
	}

}

创建两个需要命中的对象 userService 和 orderService 

@Component
public class UserService {

	public void uService01(){
		System.out.println("uService01");
	}

	public void uService02(){
		System.out.println("uService02");
	}

	public void uService03(){
		System.out.println("uService03");
	}
}
@Component
public class OrderService {

	public void oService01(){
		System.out.println("oService01");
	}

	public void oService02(){
		System.out.println("oService02");
	}

	public void oService03(){
		System.out.println("oService03");
	}
}

测试代码,只有第二次匹配到的方法对象才需要进行代理

public class Test {

	public static void main(String[] args) {
		String pointCutExpression = "execution(public * org.springframework.waf.UserService.uService01(..))";
		Class<?> clazz = UserService.class;
		AspectJExpressionPointCut expressionPointCut = new AspectJExpressionPointCut(pointCutExpression);
		if(expressionPointCut.oneMatches(clazz)){
			System.out.println("oneMatches ok");
			for (Method method : clazz.getDeclaredMethods()) {
				System.out.println(method);
				if(expressionPointCut.twoMatches(method)){
					System.out.println("twoMatches ok");
				}else{
					System.out.println("twoMatches error");
				}
			}
		}else{
			System.out.println("oneMatches error");
		}
	}
}

 打印结果正好命中了这个方法。另外表达式未包含的方法没有命中。但是这个对象仍需要被代理

oneMatches ok
public void org.springframework.waf.UserService.uService01()
twoMatches ok
public void org.springframework.waf.UserService.uService03()
twoMatches error
public void org.springframework.waf.UserService.uService02()
twoMatches error

换一个表达式

String pointCutExpression = "execution(public * org.springframework.waf.OrderService.*(..))";
Class<?> clazz = OrderService.class;

运行结果

oneMatches ok
public void org.springframework.waf.OrderService.oService01()
twoMatches ok
public void org.springframework.waf.OrderService.oService03()
twoMatches ok
public void org.springframework.waf.OrderService.oService02()
twoMatches ok

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐