try { // 若是 equals 方法不需要代理 if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { // The target does not implement the equals(Object) method itself. return equals(args[0]); } // 若是 hashCode 方法不需要代理 elseif (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { // The target does not implement the hashCode() method itself. return hashCode(); } // 若是 DecoratingProxy 也不要拦截器执行 elseif (method.getDeclaringClass() == DecoratingProxy.class) { // There is only getDecoratedClass() declared -> dispatch to proxy config. return AopProxyUtils.ultimateTargetClass(this.advised); } // isAssignableFrom 方法:如果调用这个方法的 class 或接口与参数 cls 表示的类或接口相同,或者是参数 cls 表示的类或接口的父类,则返回 true elseif (!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;
/** * 这个配置是暴露我们的代理对象到线程变量中,需要搭配@EnableAspectJAutoProxy(exposeProxy = true)一起使用 * 比如在目标对象方法中再次获取代理对象可以使用这个AopContext.currentProxy() * 还有的就是事务方法调用事务方法的时候也是用到这个 */ 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 Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method. // 从 Advised 中根据方法名和目标类获取AOP拦截器执行链 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. // 通过反射直接调用执行 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); // 如果没有发现任何拦截器那么直接调用切点方法 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { // We need to create a method invocation... // 将拦截器封装在 ReflectiveMethodInvocation,以便于使用其 proceed 进行处理 MethodInvocationinvocation= newReflectiveMethodInvocation(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; } // 返回值类型错误 elseif (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { thrownewAopInvocationException( "Null return value from advice does not match primitive return type for: " + method); } return retVal; } finally { // 如果目标对象不为空且目标对象是可变的,如prototype类型 // 通常我们的目标对象都是单例的,即targetSource.isStatic为true if (target != null && !targetSource.isStatic()) { // Must have come from TargetSource. // 释放目标对象 targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. // 线程上下文复位 AopContext.setCurrentProxy(oldProxy); } } }
public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource()); }
try { // 从advised中获取ioc容器中配置的target对象 Class<?> rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
// 获取callbacks Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = newClass<?>[callbacks.length]; for (intx=0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(newProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance. // 通过 Enhancer 生成代理对象,并设置回调 return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException | IllegalArgumentException ex) { thrownewAopConfigException("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 thrownewAopConfigException("Unexpected AOP exception", ex); } }
// Choose an "aop" interceptor (used for AOP calls). // 将拦截器封装在 DynamicAdvisedInterceptor 中 CallbackaopInterceptor=newDynamicAdvisedInterceptor(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 ? newStaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : newDynamicUnadvisedExposedInterceptor(this.advised.getTargetSource())); } else { targetInterceptor = (isStatic ? newStaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : newDynamicUnadvisedInterceptor(this.advised.getTargetSource())); }
// Choose a "direct to target" dispatcher (used for // unadvised calls to static targets that cannot return this). CallbacktargetDispatcher= (isStatic ? newStaticDispatcher(this.advised.getTargetSource().getTarget()) : newSerializableNoOp());
Callback[] mainCallbacks = newCallback[] { // 将拦截器链加入 Callback 中 aopInterceptor, // for normal advice targetInterceptor, // invoke target without considering advice, if optimized newSerializableNoOp(), // no override for methods mapped to this targetDispatcher, this.advisedDispatcher, newEqualsInterceptor(this.advised), newHashCodeInterceptor(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 = newCallback[methods.length]; this.fixedInterceptorMap = newHashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice) for (intx=0; x < methods.length; x++) { Methodmethod= methods[x]; List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass); fixedCallbacks[x] = newFixedChainStaticTargetInterceptor( 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 = newCallback[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; }
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)throws Throwable { ObjectoldProxy=null; booleansetProxyContext=false; Objecttarget=null; TargetSourcetargetSource=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); // 从advised中获取配置好的AOP通知 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. // 如果没有 aop 通知配置,那么直接调用 target 对象的调用方法 if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { // 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 = methodProxy.invoke(target, argsToUse); } else { // We need to create a method invocation... // 通过cglibMethodInvocation来启动advice通知 retVal = newCglibMethodInvocation(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); } } }