Spring---AspectJ与Spring
/**
* 【代理对象创建】
*
* 实现思路:BeanPostProcessor#postProcessAfterInitialization
*
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
*
* ->
*
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
*
* ->
*
* org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization{
*
* public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
* ...
* return wrapIfNecessary(bean, beanName, cacheKey);
* ...
* }
*
* protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
* ...
* Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
* ...
* }
*
* protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
* ...
* ProxyFactory proxyFactory = new ProxyFactory();
* ...
* return proxyFactory.getProxy(getProxyClassLoader());
* }
* }
*
*
* BeanPostProcessor : org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
*
*
*
*/
》》》》》》执行链路《《《《《《
代理Bean方法调用 -> advice被执行 -> 目标Bean方法调用 -> 增强结束
@Controller
@ResponseBody
public class MyController{
@Autowired
private AspectJServiceImpl aspectJService;
@GetMapping(value = "testAspectJ/{s}")
public void testAspectJ(@PathVariable(value = "s") String s){
aspectJService.testAspectJ(new User());
}
}
@Service
public class AspectJServiceImpl{
public void testAspectJ(User s) {
String name = this.getClass().getName();
}
}
@Component
@Aspect
public class MyAspect {
@Around("execution(public void com.an.service.impl.AspectJServiceImpl.testAspectJ(com.an.entity.User))")
public Object testAspectJ(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object[] args = proceedingJoinPoint.getArgs();
return proceedingJoinPoint.proceed(args);
}
}
生成的class
public class AspectJServiceImpl$$EnhancerBySpringCGLIB$$26f80466 extends AspectJServiceImpl implements SpringProxy, Advised, Factory {
private boolean CGLIB$BOUND;
private MethodInterceptor CGLIB$CALLBACK_0;
private MethodInterceptor CGLIB$CALLBACK_1;
private NoOp CGLIB$CALLBACK_2;
private Dispatcher CGLIB$CALLBACK_3;
private Dispatcher CGLIB$CALLBACK_4;
private MethodInterceptor CGLIB$CALLBACK_5;
private MethodInterceptor CGLIB$CALLBACK_6;
...
public final void testAspectJ(User var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
var10000.intercept(this, CGLIB$testAspectJ$1$Method, new Object[]{var1}, CGLIB$testAspectJ$1$Proxy);
} else {
super.testAspectJ(var1);
}
}
...
}
Controller中从容器中取到的Bean为代理Bean

当执行Controller的aspectJService.testAspectJ,实际调用的是代理Bean的testAspectJ;
代理Bean的this.CGLIB$CALLBACK_0 是 org.springframework.aop.framework.CglibAopProxy的内部类org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor;
然后调用DynamicAdvisedInterceptor的intercept方法;
获取所有的advice,封装到CglibAopProxy内部类org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation;
然后调用CglibMethodInvocation的proceed方法;


CglibMethodInvocation的proceed方法调用父类org.springframework.aop.framework.ReflectiveMethodInvocation的proceed方法
获取第一个advice org.springframework.aop.interceptor.ExposeInvocationInterceptor
然后调用org.springframework.aop.interceptor.ExposeInvocationInterceptor的invoke方法

org.springframework.aop.interceptor.ExposeInvocationInterceptor的invoke方法回调了org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation的proceed方法

然后取出第2个advice org.springframework.aop.aspectj.AspectJAroundAdvice
调用AspectJAroundAdvice的invoke方法


然后调用父类org.springframework.aop.aspectj.AbstractAspectJAdvice的invokeAdviceMethodWithGivenArgs方法

然后调用自定义MyAspect的方法


回调org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation的proceed方法
回调CglibMethodInvocation父类org.springframework.aop.framework.ReflectiveMethodInvocation的proceed方法


当advice执行完时,调用org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation的invokeJoinpoint方法

调用目标Bean的testAspectJ方法

调用链路结束
浙公网安备 33010602011771号