设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间14 现在时间14 缓存数据 “你总爱编织谎言,我总是配合表演。”

“你总爱编织谎言,我总是配合表演。” -- 配合

查看: 756|回复: 3

spring aop底层源码执行逻辑剖析(源码解析)

[复制链接]

  离线 

TA的专栏

  • 打卡等级:无名新人
  • 打卡总天数:1
  • 打卡月天数:0
  • 打卡总奖励:18
  • 最近打卡:2024-01-20 00:17:53
等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
34
主题
24
精华
0
金钱
114
积分
66
注册时间
2023-10-4
最后登录
2025-5-26

发表于 2024-9-22 07:10:41 | 显示全部楼层 |阅读模式
目录
  • aop动态代理源码剖析
  • 创建动态代理底层逻辑createProxy()
  • 使用jdk的方式创建动态代理
  • 使用cglib的方式创建动态代理

aop动态代理源码剖析

aop增强逻辑的执行时机是在initializeBean方法中

  1. protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
  2. if (beanName.indexOf("my") >= 0) {
  3. System.out.println("============= [initializeBean] beanName=" + beanName + " =============");
  4. }
  5. if (System.getSecurityManager() != null) {
  6. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  7. invokeAwareMethods(beanName, bean);
  8. return null;
  9. }, getAccessControlContext());
  10. }
  11. else {
  12. invokeAwareMethods(beanName, bean);
  13. }
  14. Object wrappedBean = bean;
  15. if (mbd == null || !mbd.isSynthetic()) {
  16. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  17. }
  18. try {
  19. invokeInitMethods(beanName, wrappedBean, mbd);
  20. }
  21. catch (Throwable ex) {
  22. throw new BeanCreationException(
  23. (mbd != null ? mbd.getResourceDescription() : null),
  24. beanName, "Invocation of init method failed", ex);
  25. }
  26. if (mbd == null || !mbd.isSynthetic()) {
  27. // aop增强逻辑的执行时机
  28. // 说白了就是在BeanPostProcessor#postProcessAfterInitialization
  29. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  30. }
  31. return wrappedBean;
  32. }
复制代码

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

  1. @Override
  2. public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
  3. if (bean != null) {
  4. Object cacheKey = getCacheKey(bean.getClass(), beanName);
  5. if (this.earlyProxyReferences.remove(cacheKey) != bean) {
  6. // 如果它有资格被代理
  7. return wrapIfNecessary(bean, beanName, cacheKey);
  8. }
  9. }
  10. return bean;
  11. }
复制代码
  1. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  2. // 以下三种情况,判断,如果不需要增强,就直接返回
  3. if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
  4. return bean;
  5. }
  6. if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
  7. return bean;
  8. }
  9. // 如果是 基础设施类(Pointcut、Advice、Advisor 等) 或 需要 skip, 则不需要增强
  10. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
  11. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  12. return bean;
  13. }
  14. // Create proxy if we have advice.
  15. // 为目标 bean 查找合适的通知器,并封装成一个排好顺序的List<Advisor>集合
  16. // 底层是基于拓扑排序
  17. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  18. if (specificInterceptors != DO_NOT_PROXY) {
  19. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  20. // 创建代理
  21. Object proxy = createProxy(
  22. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  23. this.proxyTypes.put(cacheKey, proxy.getClass());
  24. return proxy;
  25. }
  26. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  27. return bean;
  28. }
复制代码
  1. protected boolean isInfrastructureClass(Class<?> beanClass) {
  2. // 下面这些是基础设施类,说白了就是aop的一些配置类,是不需要被增强的
  3. boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
  4. Pointcut.class.isAssignableFrom(beanClass) ||
  5. Advisor.class.isAssignableFrom(beanClass) ||
  6. AopInfrastructureBean.class.isAssignableFrom(beanClass);
  7. if (retVal && logger.isTraceEnabled()) {
  8. logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
  9. }
  10. return retVal;
  11. }
复制代码

创建动态代理底层逻辑createProxy()

  1. protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
  2. @Nullable Object[] specificInterceptors, TargetSource targetSource) {
  3. if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
  4. AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
  5. }
  6. // 通过代理工厂创建代理
  7. ProxyFactory proxyFactory = new ProxyFactory();
  8. proxyFactory.copyFrom(this);
  9. // 设置代理模式
  10. // 在EnableAspectJAutoProxy注解中,有一个属性proxyTargetClass
  11. // boolean proxyTargetClass() default false;
  12. // 表示默认使用的是jdk动态代理,如果设置为true则会使用cglib动态代理
  13. if (proxyFactory.isProxyTargetClass()) {
  14. // Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
  15. if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
  16. // Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
  17. for (Class<?> ifc : beanClass.getInterfaces()) {
  18. proxyFactory.addInterface(ifc);
  19. }
  20. }
  21. }
  22. else {
  23. // No proxyTargetClass flag enforced, let's apply our default checks...
  24. // 如果没有接口,则会赋值为true,强制使用cglib动态代理
  25. if (shouldProxyTargetClass(beanClass, beanName)) {
  26. proxyFactory.setProxyTargetClass(true);
  27. }
  28. else {
  29. evaluateProxyInterfaces(beanClass, proxyFactory);
  30. }
  31. }
  32. Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
  33. proxyFactory.addAdvisors(advisors);
  34. proxyFactory.setTargetSource(targetSource);
  35. customizeProxyFactory(proxyFactory);
  36. proxyFactory.setFrozen(this.freezeProxy);
  37. if (advisorsPreFiltered()) {
  38. proxyFactory.setPreFiltered(true);
  39. }
  40. // Use original ClassLoader if bean class not locally loaded in overriding class loader
  41. ClassLoader classLoader = getProxyClassLoader();
  42. if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
  43. classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
  44. }
  45. // 使用工厂模式真正创建动态代理
  46. return proxyFactory.getProxy(classLoader);
  47. }
复制代码

proxyFactory.getProxy(classLoader);底层逻辑

  1. public Object getProxy(@Nullable ClassLoader classLoader) {
  2. // 创建 AopProxy 对象
  3. // 调用 AopProxy.getProxy 创建代理对象
  4. return createAopProxy().getProxy(classLoader);
  5. }
复制代码
  1. @Override
  2. public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
  3. if (!NativeDetector.inNativeImage() &&
  4. (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
  5. Class<?> targetClass = config.getTargetClass();
  6. if (targetClass == null) {
  7. throw new AopConfigException("TargetSource cannot determine target class: " +
  8. "Either an interface or a target is required for proxy creation.");
  9. }
  10. if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
  11. return new JdkDynamicAopProxy(config);// 使用jdk创建动态代理
  12. }
  13. return new ObjenesisCglibAopProxy(config); // 使用cglib创建动态代理
  14. }
  15. else {
  16. return new JdkDynamicAopProxy(config);// 使用jdk创建动态代理
  17. }
  18. }
复制代码

1.png

使用jdk的方式创建动态代理

org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)

  1. @Override
  2. public Object getProxy(@Nullable ClassLoader classLoader) {
  3. if (logger.isTraceEnabled()) {
  4. logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
  5. }
  6. return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
  7. }
复制代码

因为jdk动态代理的最重要的方法是java.lang.reflect.InvocationHandler#invoke

重点看该类中的invoke方法

  1. @Override
  2. @Nullable
  3. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  4. Object oldProxy = null;
  5. boolean setProxyContext = false;
  6. TargetSource targetSource = this.advised.targetSource;
  7. Object target = null;
  8. try {
  9. if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
  10. // The target does not implement the equals(Object) method itself.
  11. return equals(args[0]);
  12. }
  13. else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
  14. // The target does not implement the hashCode() method itself.
  15. return hashCode();
  16. }
  17. else if (method.getDeclaringClass() == DecoratingProxy.class) {
  18. // There is only getDecoratedClass() declared -> dispatch to proxy config.
  19. return AopProxyUtils.ultimateTargetClass(this.advised);
  20. }
  21. else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
  22. method.getDeclaringClass().isAssignableFrom(Advised.class)) {
  23. // Service invocations on ProxyConfig with the proxy config...
  24. return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
  25. }
  26. Object retVal;
  27. if (this.advised.exposeProxy) {
  28. // Make invocation available if necessary.
  29. oldProxy = AopContext.setCurrentProxy(proxy);
  30. setProxyContext = true;
  31. }
  32. // Get as late as possible to minimize the time we "own" the target,
  33. // in case it comes from a pool.
  34. target = targetSource.getTarget();
  35. Class<?> targetClass = (target != null ? target.getClass() : null);
  36. // Get the interception chain for this method.
  37. // 获取到所有的通知拦截器
  38. // 0 = {ExposeInvocationInterceptor}
  39. // 1 = {AspectJAroundAdvice}
  40. // 2 = {MethodBeforeAdviceInterceptor}
  41. // 3 = {AspectJAfterAdvice}
  42. // 4 = {AfterReturningAdviceInterceptor}
  43. // 5 = {AspectJAfterThrowingAdvice}
  44. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  45. // Check whether we have any advice. If we don't, we can fallback on direct
  46. // reflective invocation of the target, and avoid creating a MethodInvocation.
  47. if (chain.isEmpty()) {
  48. // We can skip creating a MethodInvocation: just invoke the target directly
  49. // Note that the final invoker must be an InvokerInterceptor so we know it does
  50. // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
  51. // 如果没有拦截器,则直接调用目标方法
  52. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
  53. retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
  54. }
  55. else {
  56. // We need to create a method invocation...
  57. // 创建一个方法调用器,将拦截器链传入
  58. MethodInvocation invocation =
  59. new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
  60. // Proceed to the joinpoint through the interceptor chain.
  61. // 通过拦截器链进入连接点。
  62. retVal = invocation.proceed();
  63. }
  64. // Massage return value if necessary.
  65. Class<?> returnType = method.getReturnType();
  66. if (retVal != null && retVal == target &&
  67. returnType != Object.class && returnType.isInstance(proxy) &&
  68. !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
  69. // Special case: it returned "this" and the return type of the method
  70. // is type-compatible. Note that we can't help if the target sets
  71. // a reference to itself in another returned object.
  72. retVal = proxy;
  73. }
  74. else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
  75. throw new AopInvocationException(
  76. "Null return value from advice does not match primitive return type for: " + method);
  77. }
  78. return retVal;
  79. }
  80. finally {
  81. if (target != null && !targetSource.isStatic()) {
  82. // Must have come from TargetSource.
  83. targetSource.releaseTarget(target);
  84. }
  85. if (setProxyContext) {
  86. // Restore old proxy.
  87. AopContext.setCurrentProxy(oldProxy);
  88. }
  89. }
  90. }
复制代码

org.springframework.aop.framework.ReflectiveMethodInvocation#proceed

  1. /**
  2. * Index from 0 of the current interceptor we're invoking.
  3. * -1 until we invoke: then the current interceptor.
  4. */
  5. // 我们正在调用的拦截器的索引
  6. private int currentInterceptorIndex = -1;
  7. @Override
  8. @Nullable
  9. public Object proceed() throws Throwable {
  10. // We start with an index of -1 and increment early.
  11. // 也就是说当所有拦截器都执行完成后,执行目标方法
  12. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
  13. return invokeJoinpoint(); // 目标方法的执行
  14. }
  15. // interceptorsAndDynamicMethodMatchers表示我们通过构造方法传过来的拦截器
  16. // interceptorOrInterceptionAdvice:渠道的拦截器(或者叫做切面逻辑)
  17. Object interceptorOrInterceptionAdvice =
  18. this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
  19. if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
  20. // Evaluate dynamic method matcher here: static part will already have
  21. // been evaluated and found to match.
  22. InterceptorAndDynamicMethodMatcher dm =
  23. (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
  24. Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
  25. if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
  26. return dm.interceptor.invoke(this);
  27. }
  28. else {
  29. // Dynamic matching failed.
  30. // Skip this interceptor and invoke the next in the chain.
  31. return proceed();
  32. }
  33. }
  34. else {
  35. // It's an interceptor, so we just invoke it: The pointcut will have
  36. // been evaluated statically before this object was constructed.
  37. // 通过不同的拦截器完成切面逻辑
  38. // 也就是说执行该拦截器的切面逻辑
  39. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
  40. }
  41. }
复制代码

解下来看看这6个切面的执行逻辑:
// 0 = {ExposeInvocationInterceptor}
// 1 = {AspectJAroundAdvice}
// 2 = {MethodBeforeAdviceInterceptor}
// 3 = {AspectJAfterAdvice}
// 4 = {AfterReturningAdviceInterceptor}
// 5 = {AspectJAfterThrowingAdvice}

org.springframework.aop.interceptor.ExposeInvocationInterceptor#invoke

  1. @Override
  2. @Nullable
  3. public Object invoke(MethodInvocation mi) throws Throwable {
  4. MethodInvocation oldInvocation = invocation.get();
  5. invocation.set(mi);
  6. try {
  7. return mi.proceed(); // 没有任何执行逻辑,直接调用目标方法
  8. }
  9. finally {
  10. invocation.set(oldInvocation);
  11. }
  12. }
复制代码

org.springframework.aop.aspectj.AspectJAroundAdvice#invoke

  1. @Override
  2. @Nullable
  3. public Object invoke(MethodInvocation mi) throws Throwable {
  4. if (!(mi instanceof ProxyMethodInvocation)) {
  5. throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
  6. }
  7. ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
  8. ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
  9. JoinPointMatch jpm = getJoinPointMatch(pmi);
  10. return invokeAdviceMethod(pjp, jpm, null, null); // 直接调用自定义的逻辑
  11. }
复制代码

org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor#invoke

  1. @Override
  2. @Nullable
  3. public Object invoke(MethodInvocation mi) throws Throwable {
  4. // 先调用自定的before方法
  5. this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
  6. // 在调用目标方法
  7. return mi.proceed();
  8. }
复制代码

org.springframework.aop.aspectj.AspectJAfterAdvice#invoke

  1. @Override
  2. @Nullable
  3. public Object invoke(MethodInvocation mi) throws Throwable {
  4. try {
  5. return mi.proceed(); // 先调用目标方法
  6. }
  7. finally {
  8. // 再调用自定义的after方法
  9. // 这个方法放在了finally块中,不然会执行
  10. invokeAdviceMethod(getJoinPointMatch(), null, null);
  11. }
  12. }
复制代码

org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor#invoke

  1. @Override
  2. @Nullable
  3. public Object invoke(MethodInvocation mi) throws Throwable {
  4. // 先执行目标方法
  5. Object retVal = mi.proceed();
  6. // 没有异常的情况下,再执行自定义的afterReturning逻辑,
  7. this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
  8. return retVal;
  9. }
复制代码

org.springframework.aop.aspectj.AspectJAfterThrowingAdvice#invoke

  1. @Override
  2. @Nullable
  3. public Object invoke(MethodInvocation mi) throws Throwable {
  4. try {
  5. // 先执行目标方法
  6. return mi.proceed();
  7. }
  8. catch (Throwable ex) {
  9. if (shouldInvokeOnThrowing(ex)) {
  10. // 如果出现异常的时候,执行自定义的afterThrowing方法
  11. invokeAdviceMethod(getJoinPointMatch(), null, ex);
  12. }
  13. throw ex;
  14. }
  15. }
复制代码

自己最好debug看看这样理解的更加深刻

2.png

使用cglib的方式创建动态代理

cglib动态代理主要是Enhancer,是创建目标类的子类来完成的动态代理。

重点关注:intercept方法

org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)

  1. @Override
  2. public Object getProxy(@Nullable ClassLoader classLoader) {
  3. if (logger.isTraceEnabled()) {
  4. logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
  5. }
  6. try {
  7. Class<?> rootClass = this.advised.getTargetClass();
  8. Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
  9. Class<?> proxySuperClass = rootClass;
  10. if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
  11. proxySuperClass = rootClass.getSuperclass();
  12. Class<?>[] additionalInterfaces = rootClass.getInterfaces();
  13. for (Class<?> additionalInterface : additionalInterfaces) {
  14. this.advised.addInterface(additionalInterface);
  15. }
  16. }
  17. // Validate the class, writing log messages as necessary.
  18. validateClassIfNecessary(proxySuperClass, classLoader);
  19. // 配置 CGLIB 增强器...
  20. // Configure CGLIB Enhancer...
  21. Enhancer enhancer = createEnhancer();
  22. if (classLoader != null) {
  23. enhancer.setClassLoader(classLoader);
  24. if (classLoader instanceof SmartClassLoader &&
  25. ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
  26. enhancer.setUseCache(false);
  27. }
  28. }
  29. // 目标代理类 class com.coding.spring.aop.bean.MyAOPBean
  30. enhancer.setSuperclass(proxySuperClass);
  31. enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
  32. enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
  33. enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
  34. // 0 = DynamicAdvisedInterceptor
  35. // 1 = StaticUnadvisedInterceptor
  36. // 2 = SerializableNoOp
  37. // 3 = StaticDispatcher
  38. // 4 = AdvisedDispatcher
  39. // 5 = EqualsInterceptor
  40. // 6 = HashCodeInterceptor
  41. Callback[] callbacks = getCallbacks(rootClass);
  42. Class<?>[] types = new Class<?>[callbacks.length];
  43. for (int x = 0; x < types.length; x++) {
  44. types[x] = callbacks[x].getClass();
  45. }
  46. // fixedInterceptorMap only populated at this point, after getCallbacks call above
  47. enhancer.setCallbackFilter(new ProxyCallbackFilter(
  48. this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
  49. enhancer.setCallbackTypes(types);
  50. // 生成代理类并创建代理实例。
  51. // Generate the proxy class and create a proxy instance.
  52. return createProxyClassAndInstance(enhancer, callbacks);
  53. }
  54. catch (CodeGenerationException | IllegalArgumentException ex) {
  55. throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
  56. ": Common causes of this problem include using a final class or a non-visible class",
  57. ex);
  58. }
  59. catch (Throwable ex) {
  60. // TargetSource.getTarget() failed
  61. throw new AopConfigException("Unexpected AOP exception", ex);
  62. }
  63. }
复制代码
  1. private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
  2. // Parameters used for optimization choices...
  3. boolean exposeProxy = this.advised.isExposeProxy();
  4. boolean isFrozen = this.advised.isFrozen();
  5. boolean isStatic = this.advised.getTargetSource().isStatic();
  6. // Choose an "aop" interceptor (used for AOP calls).
  7. // AOP 回调接口 DynamicAdvisedInterceptor
  8. // private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
  9. Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
  10. // Choose a "straight to target" interceptor. (used for calls that are
  11. // unadvised but can return this). May be required to expose the proxy.
  12. Callback targetInterceptor;
  13. if (exposeProxy) {
  14. targetInterceptor = (isStatic ?
  15. new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
  16. new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
  17. }
  18. else {
  19. targetInterceptor = (isStatic ?
  20. new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
  21. new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
  22. }
  23. // Choose a "direct to target" dispatcher (used for
  24. // unadvised calls to static targets that cannot return this).
  25. Callback targetDispatcher = (isStatic ?
  26. new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
  27. Callback[] mainCallbacks = new Callback[] {
  28. aopInterceptor, // for normal advice
  29. targetInterceptor, // invoke target without considering advice, if optimized
  30. new SerializableNoOp(), // no override for methods mapped to this
  31. targetDispatcher, this.advisedDispatcher,
  32. new EqualsInterceptor(this.advised),
  33. new HashCodeInterceptor(this.advised)
  34. };
  35. Callback[] callbacks;
  36. // If the target is a static one and the advice chain is frozen,
  37. // then we can make some optimizations by sending the AOP calls
  38. // direct to the target using the fixed chain for that method.
  39. if (isStatic && isFrozen) {
  40. Method[] methods = rootClass.getMethods();
  41. Callback[] fixedCallbacks = new Callback[methods.length];
  42. this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);
  43. // TODO: small memory optimization here (can skip creation for methods with no advice)
  44. for (int x = 0; x < methods.length; x++) {
  45. Method method = methods[x];
  46. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
  47. fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
  48. chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
  49. this.fixedInterceptorMap.put(method, x);
  50. }
  51. // Now copy both the callbacks from mainCallbacks
  52. // and fixedCallbacks into the callbacks array.
  53. callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
  54. System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
  55. System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
  56. this.fixedInterceptorOffset = mainCallbacks.length;
  57. }
  58. else {
  59. callbacks = mainCallbacks;
  60. }
  61. return callbacks;
  62. }
复制代码
  1. // 可以看到MethodInterceptor实现了Callback接口
  2. public interface MethodInterceptor extends Callback {
  3. Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
  4. }
复制代码
  1. /**
  2. * General purpose AOP callback. Used when the target is dynamic or when the
  3. * proxy is not frozen.
  4. */
  5. private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
  6. private final AdvisedSupport advised;
  7. public DynamicAdvisedInterceptor(AdvisedSupport advised) {
  8. this.advised = advised;
  9. }
  10. // CglibAopProxy.DynamicAdvisedInterceptor.intercept
  11. // 最终创建动态代理之后,会调用到这个intercept方法
  12. @Override
  13. @Nullable
  14. public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
  15. Object oldProxy = null;
  16. boolean setProxyContext = false;
  17. Object target = null;
  18. TargetSource targetSource = this.advised.getTargetSource();
  19. try {
  20. if (this.advised.exposeProxy) {
  21. // Make invocation available if necessary.
  22. oldProxy = AopContext.setCurrentProxy(proxy);
  23. setProxyContext = true;
  24. }
  25. // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
  26. target = targetSource.getTarget();
  27. Class<?> targetClass = (target != null ? target.getClass() : null);
  28. // 0 = {ExposeInvocationInterceptor}
  29. // 1 = {AspectJAroundAdvice}
  30. // 2 = {MethodBeforeAdviceInterceptor}
  31. // 3 = {AspectJAfterAdvice}
  32. // 4 = {AfterReturningAdviceInterceptor}
  33. // 5 = {AspectJAfterThrowingAdvice}
  34. // 获取拦截器链
  35. List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  36. Object retVal;
  37. // Check whether we only have one InvokerInterceptor: that is,
  38. // no real advice, but just reflective invocation of the target.
  39. if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
  40. // We can skip creating a MethodInvocation: just invoke the target directly.
  41. // Note that the final invoker must be an InvokerInterceptor, so we know
  42. // it does nothing but a reflective operation on the target, and no hot
  43. // swapping or fancy proxying.
  44. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
  45. retVal = invokeMethod(target, method, argsToUse, methodProxy);
  46. }
  47. else {
  48. // We need to create a method invocation...
  49. // 创建 CglibMethodInvocation 进行proceed()方法调用
  50. retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
  51. }
  52. retVal = processReturnType(proxy, target, method, retVal);
  53. return retVal;
  54. }
  55. finally {
  56. if (target != null && !targetSource.isStatic()) {
  57. targetSource.releaseTarget(target);
  58. }
  59. if (setProxyContext) {
  60. // Restore old proxy.
  61. AopContext.setCurrentProxy(oldProxy);
  62. }
  63. }
  64. }
  65. @Override
  66. public boolean equals(@Nullable Object other) {
  67. return (this == other ||
  68. (other instanceof DynamicAdvisedInterceptor &&
  69. this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));
  70. }
  71. /**
  72. * CGLIB uses this to drive proxy creation.
  73. */
  74. @Override
  75. public int hashCode() {
  76. return this.advised.hashCode();
  77. }
  78. }
复制代码

org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation#proceed

  1. @Override
  2. @Nullable
  3. public Object proceed() throws Throwable {
  4. try {
  5. // 调用 ReflectiveMethodInvocation.proceed
  6. return super.proceed();
  7. }
  8. catch (RuntimeException ex) {
  9. throw ex;
  10. }
  11. catch (Exception ex) {
  12. if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) ||
  13. KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) {
  14. // Propagate original exception if declared on the target method
  15. // (with callers expecting it). Always propagate it for Kotlin code
  16. // since checked exceptions do not have to be explicitly declared there.
  17. throw ex;
  18. }
  19. else {
  20. // Checked exception thrown in the interceptor but not declared on the
  21. // target method signature -> apply an UndeclaredThrowableException,
  22. // aligned with standard JDK dynamic proxy behavior.
  23. throw new UndeclaredThrowableException(ex);
  24. }
  25. }
  26. }
复制代码

org.springframework.aop.framework.ObjenesisCglibAopProxy#createProxyClassAndInstance

  1. @Override
  2. protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
  3. Class<?> proxyClass = enhancer.createClass();
  4. Object proxyInstance = null;
  5. if (objenesis.isWorthTrying()) {
  6. try {
  7. // 创建代理类实例
  8. proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
  9. }
  10. catch (Throwable ex) {
  11. logger.debug("Unable to instantiate proxy using Objenesis, " +
  12. "falling back to regular proxy construction", ex);
  13. }
  14. }
  15. if (proxyInstance == null) {
  16. // Regular instantiation via default constructor...
  17. try {
  18. Constructor<?> ctor = (this.constructorArgs != null ?
  19. proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
  20. proxyClass.getDeclaredConstructor());
  21. ReflectionUtils.makeAccessible(ctor);
  22. proxyInstance = (this.constructorArgs != null ?
  23. ctor.newInstance(this.constructorArgs) : ctor.newInstance());
  24. }
  25. catch (Throwable ex) {
  26. throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
  27. "and regular proxy instantiation via default constructor fails as well", ex);
  28. }
  29. }
  30. // 设置 callBack 回调接口
  31. ((Factory) proxyInstance).setCallbacks(callbacks);
  32. return proxyInstance;
  33. }
复制代码

org.springframework.aop.framework.ReflectiveMethodInvocation#proceed

  1. @Override
  2. @Nullable
  3. public Object proceed() throws Throwable {
  4. // We start with an index of -1 and increment early.
  5. // 所有拦截器都执行完成后,执行目标方法
  6. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
  7. return invokeJoinpoint();
  8. }
  9. Object interceptorOrInterceptionAdvice =
  10. this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
  11. if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
  12. // Evaluate dynamic method matcher here: static part will already have
  13. // been evaluated and found to match.
  14. InterceptorAndDynamicMethodMatcher dm =
  15. (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
  16. Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
  17. if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
  18. return dm.interceptor.invoke(this);
  19. }
  20. else {
  21. // Dynamic matching failed.
  22. // Skip this interceptor and invoke the next in the chain.
  23. return proceed();
  24. }
  25. }
  26. else {
  27. // It's an interceptor, so we just invoke it: The pointcut will have
  28. // been evaluated statically before this object was constructed.
  29. // 通过不同的拦截器完成切面逻辑
  30. // 看到这里就和jdk动态代理的逻辑是一样的了
  31. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
  32. }
  33. }
复制代码

后面的执行逻辑就和上面jdk动态代理的执行逻辑一样了。

到此这篇关于spring aop底层源码执行逻辑剖析的文章就介绍到这了,更多相关spring aop底层源码内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
20
积分
20
注册时间
2022-12-26
最后登录
2022-12-26

发表于 2025-2-21 21:48:12 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
18
积分
16
注册时间
2022-12-27
最后登录
2022-12-27

发表于 2025-4-1 06:22:26 | 显示全部楼层
路过,支持一下
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
13
积分
6
注册时间
2022-12-25
最后登录
2022-12-25

发表于 2025-4-15 09:45:49 | 显示全部楼层
感谢楼主,顶。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
3楼
4楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表