spring aop底層源碼執(zhí)行邏輯剖析(源碼解析)
aop動態(tài)代理源碼剖析
aop增強邏輯的執(zhí)行時機是在initializeBean方法中
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (beanName.indexOf("my") >= 0) { System.out.println("============= [initializeBean] beanName=" + beanName + " ============="); } if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // aop增強邏輯的執(zhí)行時機 // 說白了就是在BeanPostProcessor#postProcessAfterInitialization wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { // 如果它有資格被代理 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // 以下三種情況,判斷,如果不需要增強,就直接返回 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } // 如果是 基礎(chǔ)設施類(Pointcut、Advice、Advisor 等) 或 需要 skip, 則不需要增強 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 為目標 bean 查找合適的通知器,并封裝成一個排好順序的List<Advisor>集合 // 底層是基于拓撲排序 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 創(chuàng)建代理 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
protected boolean isInfrastructureClass(Class<?> beanClass) { // 下面這些是基礎(chǔ)設施類,說白了就是aop的一些配置類,是不需要被增強的 boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass); if (retVal && logger.isTraceEnabled()) { logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]"); } return retVal; }
創(chuàng)建動態(tài)代理底層邏輯createProxy()
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } // 通過代理工廠創(chuàng)建代理 ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); // 設置代理模式 // 在EnableAspectJAutoProxy注解中,有一個屬性proxyTargetClass // boolean proxyTargetClass() default false; // 表示默認使用的是jdk動態(tài)代理,如果設置為true則會使用cglib動態(tài)代理 if (proxyFactory.isProxyTargetClass()) { // Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios) if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) { // Must allow for introductions; can't just set interfaces to the proxy's interfaces only. for (Class<?> ifc : beanClass.getInterfaces()) { proxyFactory.addInterface(ifc); } } } else { // No proxyTargetClass flag enforced, let's apply our default checks... // 如果沒有接口,則會賦值為true,強制使用cglib動態(tài)代理 if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // Use original ClassLoader if bean class not locally loaded in overriding class loader ClassLoader classLoader = getProxyClassLoader(); if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) { classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader(); } // 使用工廠模式真正創(chuàng)建動態(tài)代理 return proxyFactory.getProxy(classLoader); }
proxyFactory.getProxy(classLoader);底層邏輯
public Object getProxy(@Nullable ClassLoader classLoader) { // 創(chuàng)建 AopProxy 對象 // 調(diào)用 AopProxy.getProxy 創(chuàng)建代理對象 return createAopProxy().getProxy(classLoader); }
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (!NativeDetector.inNativeImage() && (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) { return new JdkDynamicAopProxy(config);// 使用jdk創(chuàng)建動態(tài)代理 } return new ObjenesisCglibAopProxy(config); // 使用cglib創(chuàng)建動態(tài)代理 } else { return new JdkDynamicAopProxy(config);// 使用jdk創(chuàng)建動態(tài)代理 } }
使用jdk的方式創(chuàng)建動態(tài)代理
org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
@Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource()); } return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this); }
因為jdk動態(tài)代理的最重要的方法是java.lang.reflect.InvocationHandler#invoke
重點看該類中的invoke方法
@Override @Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Object target = null; try { if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { // The target does not implement the equals(Object) method itself. return equals(args[0]); } else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method itself. return hashCode(); } else if (method.getDeclaringClass() == DecoratingProxy.class) { // There is only getDecoratedClass() declared -> dispatch to proxy config. return AopProxyUtils.ultimateTargetClass(this.advised); } else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { // Service invocations on ProxyConfig with the proxy config... return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // Get as late as possible to minimize the time we "own" the target, // in case it comes from a pool. target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); // Get the interception chain for this method. // 獲取到所有的通知攔截器 // 0 = {ExposeInvocationInterceptor} // 1 = {AspectJAroundAdvice} // 2 = {MethodBeforeAdviceInterceptor} // 3 = {AspectJAfterAdvice} // 4 = {AfterReturningAdviceInterceptor} // 5 = {AspectJAfterThrowingAdvice} List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // Check whether we have any advice. If we don't, we can fallback on direct // reflective invocation of the target, and avoid creating a MethodInvocation. if (chain.isEmpty()) { // We can skip creating a MethodInvocation: just invoke the target directly // Note that the final invoker must be an InvokerInterceptor so we know it does // nothing but a reflective operation on the target, and no hot swapping or fancy proxying. // 如果沒有攔截器,則直接調(diào)用目標方法 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { // We need to create a method invocation... // 創(chuàng)建一個方法調(diào)用器,將攔截器鏈傳入 MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // Proceed to the joinpoint through the interceptor chain. // 通過攔截器鏈進入連接點。 retVal = invocation.proceed(); } // Massage return value if necessary. Class<?> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { // Special case: it returned "this" and the return type of the method // is type-compatible. Note that we can't help if the target sets // a reference to itself in another returned object. retVal = proxy; } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { throw new AopInvocationException( "Null return value from advice does not match primitive return type for: " + method); } return retVal; } finally { if (target != null && !targetSource.isStatic()) { // Must have come from TargetSource. targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
/** * Index from 0 of the current interceptor we're invoking. * -1 until we invoke: then the current interceptor. */ // 我們正在調(diào)用的攔截器的索引 private int currentInterceptorIndex = -1; @Override @Nullable public Object proceed() throws Throwable { // We start with an index of -1 and increment early. // 也就是說當所有攔截器都執(zhí)行完成后,執(zhí)行目標方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); // 目標方法的執(zhí)行 } // interceptorsAndDynamicMethodMatchers表示我們通過構(gòu)造方法傳過來的攔截器 // interceptorOrInterceptionAdvice:渠道的攔截器(或者叫做切面邏輯) Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass()); if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. // 通過不同的攔截器完成切面邏輯 // 也就是說執(zhí)行該攔截器的切面邏輯 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
解下來看看這6個切面的執(zhí)行邏輯:
// 0 = {ExposeInvocationInterceptor}
// 1 = {AspectJAroundAdvice}
// 2 = {MethodBeforeAdviceInterceptor}
// 3 = {AspectJAfterAdvice}
// 4 = {AfterReturningAdviceInterceptor}
// 5 = {AspectJAfterThrowingAdvice}
org.springframework.aop.interceptor.ExposeInvocationInterceptor#invoke
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { MethodInvocation oldInvocation = invocation.get(); invocation.set(mi); try { return mi.proceed(); // 沒有任何執(zhí)行邏輯,直接調(diào)用目標方法 } finally { invocation.set(oldInvocation); } }
org.springframework.aop.aspectj.AspectJAroundAdvice#invoke
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { if (!(mi instanceof ProxyMethodInvocation)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi); JoinPointMatch jpm = getJoinPointMatch(pmi); return invokeAdviceMethod(pjp, jpm, null, null); // 直接調(diào)用自定義的邏輯 }
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor#invoke
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { // 先調(diào)用自定的before方法 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); // 在調(diào)用目標方法 return mi.proceed(); }
org.springframework.aop.aspectj.AspectJAfterAdvice#invoke
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); // 先調(diào)用目標方法 } finally { // 再調(diào)用自定義的after方法 // 這個方法放在了finally塊中,不然會執(zhí)行 invokeAdviceMethod(getJoinPointMatch(), null, null); } }
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor#invoke
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { // 先執(zhí)行目標方法 Object retVal = mi.proceed(); // 沒有異常的情況下,再執(zhí)行自定義的afterReturning邏輯, this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; }
org.springframework.aop.aspectj.AspectJAfterThrowingAdvice#invoke
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { try { // 先執(zhí)行目標方法 return mi.proceed(); } catch (Throwable ex) { if (shouldInvokeOnThrowing(ex)) { // 如果出現(xiàn)異常的時候,執(zhí)行自定義的afterThrowing方法 invokeAdviceMethod(getJoinPointMatch(), null, ex); } throw ex; } }
自己最好debug看看這樣理解的更加深刻
使用cglib的方式創(chuàng)建動態(tài)代理
cglib動態(tài)代理主要是Enhancer,是創(chuàng)建目標類的子類來完成的動態(tài)代理。
重點關(guān)注:intercept方法
org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
@Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource()); } try { Class<?> rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy"); Class<?> proxySuperClass = rootClass; if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) { proxySuperClass = rootClass.getSuperclass(); Class<?>[] additionalInterfaces = rootClass.getInterfaces(); for (Class<?> additionalInterface : additionalInterfaces) { this.advised.addInterface(additionalInterface); } } // Validate the class, writing log messages as necessary. validateClassIfNecessary(proxySuperClass, classLoader); // 配置 CGLIB 增強器... // Configure CGLIB Enhancer... Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } // 目標代理類 class com.coding.spring.aop.bean.MyAOPBean enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader)); // 0 = DynamicAdvisedInterceptor // 1 = StaticUnadvisedInterceptor // 2 = SerializableNoOp // 3 = StaticDispatcher // 4 = AdvisedDispatcher // 5 = EqualsInterceptor // 6 = HashCodeInterceptor Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // 生成代理類并創(chuàng)建代理實例。 // Generate the proxy class and create a proxy instance. return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException | IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed throw new AopConfigException("Unexpected AOP exception", ex); } }
private Callback[] getCallbacks(Class<?> rootClass) throws Exception { // Parameters used for optimization choices... boolean exposeProxy = this.advised.isExposeProxy(); boolean isFrozen = this.advised.isFrozen(); boolean isStatic = this.advised.getTargetSource().isStatic(); // Choose an "aop" interceptor (used for AOP calls). // AOP 回調(diào)接口 DynamicAdvisedInterceptor // private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable { Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised); // Choose a "straight to target" interceptor. (used for calls that are // unadvised but can return this). May be required to expose the proxy. Callback targetInterceptor; if (exposeProxy) { targetInterceptor = (isStatic ? new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource())); } else { targetInterceptor = (isStatic ? new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new DynamicUnadvisedInterceptor(this.advised.getTargetSource())); } // Choose a "direct to target" dispatcher (used for // unadvised calls to static targets that cannot return this). Callback targetDispatcher = (isStatic ? new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp()); Callback[] mainCallbacks = new Callback[] { aopInterceptor, // for normal advice targetInterceptor, // invoke target without considering advice, if optimized new SerializableNoOp(), // no override for methods mapped to this targetDispatcher, this.advisedDispatcher, new EqualsInterceptor(this.advised), new HashCodeInterceptor(this.advised) }; Callback[] callbacks; // If the target is a static one and the advice chain is frozen, // then we can make some optimizations by sending the AOP calls // direct to the target using the fixed chain for that method. if (isStatic && isFrozen) { Method[] methods = rootClass.getMethods(); Callback[] fixedCallbacks = new Callback[methods.length]; this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length); // TODO: small memory optimization here (can skip creation for methods with no advice) for (int x = 0; x < methods.length; x++) { Method method = methods[x]; List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass); fixedCallbacks[x] = new FixedChainStaticTargetInterceptor( chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass()); this.fixedInterceptorMap.put(method, x); } // Now copy both the callbacks from mainCallbacks // and fixedCallbacks into the callbacks array. callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length]; System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length); System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length); this.fixedInterceptorOffset = mainCallbacks.length; } else { callbacks = mainCallbacks; } return callbacks; }
// 可以看到MethodInterceptor實現(xiàn)了Callback接口 public interface MethodInterceptor extends Callback { Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable; }
/** * General purpose AOP callback. Used when the target is dynamic or when the * proxy is not frozen. */ private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable { private final AdvisedSupport advised; public DynamicAdvisedInterceptor(AdvisedSupport advised) { this.advised = advised; } // CglibAopProxy.DynamicAdvisedInterceptor.intercept // 最終創(chuàng)建動態(tài)代理之后,會調(diào)用到這個intercept方法 @Override @Nullable public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; Object target = null; TargetSource targetSource = this.advised.getTargetSource(); try { if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool... target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); // 0 = {ExposeInvocationInterceptor} // 1 = {AspectJAroundAdvice} // 2 = {MethodBeforeAdviceInterceptor} // 3 = {AspectJAfterAdvice} // 4 = {AfterReturningAdviceInterceptor} // 5 = {AspectJAfterThrowingAdvice} // 獲取攔截器鏈 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; // Check whether we only have one InvokerInterceptor: that is, // no real advice, but just reflective invocation of the target. if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) { // We can skip creating a MethodInvocation: just invoke the target directly. // Note that the final invoker must be an InvokerInterceptor, so we know // it does nothing but a reflective operation on the target, and no hot // swapping or fancy proxying. Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = invokeMethod(target, method, argsToUse, methodProxy); } else { // We need to create a method invocation... // 創(chuàng)建 CglibMethodInvocation 進行proceed()方法調(diào)用 retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); } retVal = processReturnType(proxy, target, method, retVal); return retVal; } finally { if (target != null && !targetSource.isStatic()) { targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } } @Override public boolean equals(@Nullable Object other) { return (this == other || (other instanceof DynamicAdvisedInterceptor && this.advised.equals(((DynamicAdvisedInterceptor) other).advised))); } /** * CGLIB uses this to drive proxy creation. */ @Override public int hashCode() { return this.advised.hashCode(); } }
org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation#proceed
@Override @Nullable public Object proceed() throws Throwable { try { // 調(diào)用 ReflectiveMethodInvocation.proceed return super.proceed(); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) || KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) { // Propagate original exception if declared on the target method // (with callers expecting it). Always propagate it for Kotlin code // since checked exceptions do not have to be explicitly declared there. throw ex; } else { // Checked exception thrown in the interceptor but not declared on the // target method signature -> apply an UndeclaredThrowableException, // aligned with standard JDK dynamic proxy behavior. throw new UndeclaredThrowableException(ex); } } }
org.springframework.aop.framework.ObjenesisCglibAopProxy#createProxyClassAndInstance
@Override protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) { Class<?> proxyClass = enhancer.createClass(); Object proxyInstance = null; if (objenesis.isWorthTrying()) { try { // 創(chuàng)建代理類實例 proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache()); } catch (Throwable ex) { logger.debug("Unable to instantiate proxy using Objenesis, " + "falling back to regular proxy construction", ex); } } if (proxyInstance == null) { // Regular instantiation via default constructor... try { Constructor<?> ctor = (this.constructorArgs != null ? proxyClass.getDeclaredConstructor(this.constructorArgTypes) : proxyClass.getDeclaredConstructor()); ReflectionUtils.makeAccessible(ctor); proxyInstance = (this.constructorArgs != null ? ctor.newInstance(this.constructorArgs) : ctor.newInstance()); } catch (Throwable ex) { throw new AopConfigException("Unable to instantiate proxy using Objenesis, " + "and regular proxy instantiation via default constructor fails as well", ex); } } // 設置 callBack 回調(diào)接口 ((Factory) proxyInstance).setCallbacks(callbacks); return proxyInstance; }
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
@Override @Nullable public Object proceed() throws Throwable { // We start with an index of -1 and increment early. // 所有攔截器都執(zhí)行完成后,執(zhí)行目標方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass()); if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. // 通過不同的攔截器完成切面邏輯 // 看到這里就和jdk動態(tài)代理的邏輯是一樣的了 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
后面的執(zhí)行邏輯就和上面jdk動態(tài)代理的執(zhí)行邏輯一樣了。
到此這篇關(guān)于spring aop底層源碼執(zhí)行邏輯剖析的文章就介紹到這了,更多相關(guān)spring aop底層源碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實現(xiàn)上傳網(wǎng)絡圖片到微信臨時素材
這篇文章主要為大家詳細介紹了java實現(xiàn)上傳網(wǎng)絡圖片到微信臨時素材,網(wǎng)絡圖片上傳到微信服務器,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07簡單介紹區(qū)分applet和application的方法
applet和application都是Java語言編寫出來的應用程序,本文簡單介紹了二者的不同之處,需要的朋友可以參考下2017-09-09java jdk1.8 使用stream流進行l(wèi)ist 分組歸類操作
這篇文章主要介紹了java jdk1.8 使用stream流進行l(wèi)ist 分組歸類操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10springboot application.yml使用@@pom文件配置問題
這篇文章主要介紹了springboot application.yml使用@@pom文件配置問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07SpringMVC結(jié)構(gòu)簡介及常用注解匯總
這篇文章主要介紹了SpringMVC結(jié)構(gòu)簡介及常用注解匯總,幫助大家更好的理解和學習使用SpringMVC,感興趣的朋友可以了解下2021-03-03jvm調(diào)優(yōu)的幾種場景(小結(jié))
本文主要介紹了jvm調(diào)優(yōu)的幾種場景,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01Java實現(xiàn)調(diào)用ElasticSearch?API的示例詳解
這篇文章主要為大家詳細介紹了Java調(diào)用ElasticSearch?API的效果資料,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的可以了解一下2023-03-03Java并發(fā)編程中的CompletableFuture使用詳解
這篇文章主要介紹了Java并發(fā)編程中的CompletableFuture使用詳解,Future接口定義了操作異步任務執(zhí)行的一些方法,如獲取異步任務執(zhí)行的結(jié)果、取消任務的執(zhí)行、判斷任務是否被取消,判斷任務是否執(zhí)行完畢等,需要的朋友可以參考下2023-12-12