Spring-13 AOP 动态通知 & 静态通知

Spring 源码系列文章会遵循由浅入深,由易到难,由宏观到微观的原则,目标是尽量降低学习难度,而不是一上来就迷失在源码当中. 文章会从一个场景作为出发点,针对性的目的性极强的针对该场景对 Spring 的实现原理,源码进行探究学习。该系列文章会让你收获什么? 从对 Spring 的使用者成为 Spring 专家。该文章会同步在微信公众号 【DevXJava】, 方便在微信客户端阅读。

本章会介绍 AOP 静态通知动态通知, 静态通知很简单是指固定的表达式在编译器就已经确定了,动态通知 的表达式是在每次调用时动态的最终确定的。


场景
public class AopTest {

@Aspect
static class MyAspect {

// 静态通知
@Before("execution(* foo(..))")
public void before1() {
System.out.println("@Aspect @Before1 ------------------------------");
}

// 动态通知
@Before("execution(* foo(..)) && args(x)")
public void before2(int x) {
System.out.println("@Aspect @Before2 ------------------------------ x = " + x);
}

}

static class Target {
public void foo(int x) {
System.out.println("Target foo x = " + x);
}
}

public static void main(String[] args) throws Throwable {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logger = loggerContext.getLogger(AnnotationAwareAspectJAutoProxyCreator.class);
logger.setLevel(Level.TRACE);

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

AnnotationAwareAspectJAutoProxyCreator proxyCreator = new AnnotationAwareAspectJAutoProxyCreator();
proxyCreator.setBeanFactory(factory);
factory.addBeanPostProcessor(proxyCreator);

factory.registerBeanDefinition("myAspect" , BeanDefinitionBuilder
.genericBeanDefinition(MyAspect.class)
.getBeanDefinition());

// findEligibleAdvisors
Method findEligibleAdvisors = AbstractAdvisorAutoProxyCreator.class.getDeclaredMethod("findEligibleAdvisors", Class.class, String.class);
findEligibleAdvisors.setAccessible(true);
List<Advisor> advisors = (List<Advisor>) findEligibleAdvisors.invoke(proxyCreator, Target.class, "target");
for (Advisor advisor : advisors) {
System.out.println("advisor => " + advisor);
}



Target target = new Target();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetClass(Target.class);
proxyFactory.setTargetSource(new SingletonTargetSource(target));

Object proxy = proxyFactory.getProxy();

List<Object> chain = proxyFactory.getInterceptorsAndDynamicInterceptionAdvice(Target.class.getDeclaredMethod("foo" , int.class), Target.class);
for (Object c : chain) {
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> " + c);
}

Constructor<ReflectiveMethodInvocation> constructor = ReflectiveMethodInvocation.class.getDeclaredConstructor(Object.class, Object.class, Method.class, Object[].class, Class.class, List.class);
constructor.setAccessible(true);
ReflectiveMethodInvocation invocation = constructor.newInstance(proxy , target ,
Target.class.getDeclaredMethod("foo" , int.class) , new Object[]{666} , Target.class , chain);
invocation.proceed();
}

}

动态通知 InterceptorAndDynamicMethodMatcher


确定动态通知

DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice 方法内会根据 MethodMatcher 判断切面是否为动态通知。


ReflectiveMethodInvocation#proceed



DevX 会持续分享 Java 技术干货,如果你觉得本文对你有帮助希望你可以分享给更多的朋友看到。该文章会同步在微信公众号 【DevXJava】, 方便在微信客户端阅读。

DevX 不止于技术

本篇文章来源于微信公众号: DevXJava



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2023-05-28