Spring aop源码分析

it2024-10-16  17

Spring Aop源码分析

实例

public class Aop { public static void main(String[] args) { IUser user = new User(); ProxyFactory factory = new ProxyFactory(); factory.setTarget(user); factory.setInterfaces(IUser.class); factory.addAdvice(new LogAdvice()); factory.addAdvice(new Log2Advice()); factory.addAdvice(new AfterReturningAdviceInterceptor(new AfterReturningAdvice() { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("clearn-----------------"); } })); IUser proxyUser = (IUser) factory.getProxy(); proxyUser.echo(); } } public interface IUser { public void echo(); } public class LogAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("log----------"); } } public class Log2Advice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("log2----------------"); } } public class User implements IUser{ public void echo(){ System.out.println("lixinlei"); } }

源码分析

首先看一下ProxyFactory的继承层次 Advised主要提供了Advisor的管理类 ProxyConfig则提供了生成代理对象的配置管理 ProxyFactory因此可以添加Advisor和管理代理对象的配置 接下来看ProxyFactory的getProxy 可以看到首先创建一个AopProxy对象,然后通过该对象来获取代理

public Object getProxy() { return createAopProxy().getProxy(); }

获取AopProxyFactory,然后创建一个AopProxy

protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }

根据配置返回不同类型的AopProxy

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (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)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }

下面首先分析JdkDynamicAopProxy,该类继承了InvocationHandler,因此需要关注invoke方法

@Override public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { MethodInvocation invocation; Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Class<?> targetClass = null; 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; } // May be null. Get as late as possible to minimize the time we "own" the target, // in case it comes from a pool. target = targetSource.getTarget(); if (target != null) { targetClass = target.getClass(); } // Get the interception chain for this method. // 关键,获得拦截器链 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 { // 将拦截器链转换成MethodInvocation // We need to create a method invocation... 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); } } }

下面看拦截器链如何执行

public Object proceed() throws Throwable { // We start with an index of -1 and increment early. // 每个拦截器对应一个索引位置 // 如果拦截器链执行完,那么执行目标对象的方法 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; if (dm.methodMatcher.matches(this.method, this.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. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }

下面看一下不同类型拦截器的invoke方法

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { private MethodBeforeAdvice advice; /** * Create a new MethodBeforeAdviceInterceptor for the given advice. * @param advice the MethodBeforeAdvice to wrap */ public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override public Object invoke(MethodInvocation mi) throws Throwable { // 可以看到首先执行自身逻辑,然后继续沿着拦截器链执行 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() ); return mi.proceed(); } } public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable { private final AfterReturningAdvice advice; /** * Create a new AfterReturningAdviceInterceptor for the given advice. * @param advice the AfterReturningAdvice to wrap */ public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } @Override public Object invoke(MethodInvocation mi) throws Throwable { // 首先沿着拦截器链进行执行,当执行完其他的所有拦截器链已经目标对象的对应方法后,再执行自身罗炯 Object retVal = mi.proceed(); this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; } }
最新回复(0)