Spring AOP源码篇二之 代理工厂ProxyFactory学习

了解AspectJ表达式以及PointCut、Advice、Advisor后,继续学习Spring AOP代理工厂
AspectJ表达式参考:Spring AOP之AspectJ表达式-CSDN博客
PointCut、Advice、Advisor参考:Spring AOP源码篇一之 PointCut、Advice、Advisor学习-CSDN博客
简单代码示例:
package org.spring.aop.proxy.service;

public interface IUserService {
    void say();
}
package org.spring.aop.proxy.service;

public class UserService implements IUserService {
    public void say() {
        System.out.println("Hello world!!");
    }
}
package org.spring.aop.proxy.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class LogAdvice implements MethodInterceptor {
	@Override
	public Object invoke(MethodInvocation methodInvocation) throws Throwable {
		System.out.println("===============log record start==============");
		Object object = methodInvocation.proceed();
		System.out.println("===============log record end================");
		return object;
	}
}

测试代码:

package org.spring.aop.proxy;

import org.spring.aop.proxy.advice.LogAdvice;
import org.spring.aop.proxy.service.IUserService;
import org.spring.aop.proxy.service.UserService;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;

public class ProxyFactoryTest {
    public static void main(String[] args) {
        System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        IUserService service = new UserService();
        ProxyFactory proxyFactory = new ProxyFactory(service);
        IUserService serviceProxy = (IUserService) proxyFactory.getProxy();
        //不打印toString是因为代理对象底层toString调的是目标对象的toString,二者toString内容一样。
        System.out.printf("原始对象[%s]====代理对象[%s]====[比较二者:%s]\n", service.hashCode(), serviceProxy.hashCode(), (service == serviceProxy));
        serviceProxy.say();

        System.out.println("\n-------------对目标对象增强功能-----------------\n");
        String expression = "execution(* org.spring.aop.proxy.service.UserService.*(..))";
        Advisor advisor = buildAdvisor(expression);
        proxyFactory.addAdvisor(advisor);
        serviceProxy = (IUserService) proxyFactory.getProxy();
        serviceProxy.say();
    }

    public static Advisor buildAdvisor(String expression) {
        //创建pointcut
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(expression);

        //创建advice
        LogAdvice advice = new LogAdvice();

        //创建advisor
        Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);

        return advisor;
    }
}

执行结果:

代理工厂ProxyFactory继承体系

Advised是个配置管理类,对Advisor、Advice进行配置管理
package org.springframework.aop.framework;

import org.aopalliance.aop.Advice;

import org.springframework.aop.Advisor;
import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.AopConfigException;

public interface Advised extends TargetClassAware {

	/**
	 * 判断advised配置是否冻结
	 * 一旦冻结,不允许删除或增加Advisor和Adivce
	 */
	boolean isFrozen();

	/**
	 * 判断是否直接代理目标类,而不是目标类的父接口
	 * Spring中代理分为JDK动态代理、CGLIB代理;JDK动态代理的是父接口,CGLIB代理的是目标类(具体类)
	 */
	boolean isProxyTargetClass();

	/**
	 * 返回目标对象的父接口,如果目标对象类型是接口则包含其中,如果不是接口则不包含其中。
	 * 如果advice是引介增强的话,advice的接口也会放入其中。
	 */
	Class<?>[] getProxiedInterfaces();

	/**
	 * 判断指定的接口是否已被代理(被代理的接口一般是目标类的父接口,
	 * 默认Spring Aop会为目标对象的代理对象额外添加两个父接口SpringProxy、Advised)
	 */
	boolean isInterfaceProxied(Class<?> intf);


	/*
		/*public interface TargetSource extends TargetClassAware {
			/**
			 * 返回目标对象类型
			 *//*
			Class<?> getTargetClass();

			*//**
			 * 判断目标对象是否为静态
			 *//*
			boolean isStatic();

			*//**
			 * 返回目标对象
			 *//*
			Object getTarget() throws Exception;

			*//**
			 * 释放销毁目标对象(spring中该方法基本都是空实现),getTarget()时重新创建
			 *//*
			void releaseTarget(Object target) throws Exception;
		}
	 */
	/**
	 * 设置被代理的目标对象TargetSource(目标对象被封装在TargetSource)
	 */
	void setTargetSource(TargetSource targetSource);

	/**
	 * 返回被代理目标对象的TargetSource(目标对象被封装在TargetSource中)
	 */
	TargetSource getTargetSource();

	/**
	 * 代理对象是否设置到AOP框架中的ThreadLocal中
	 */
	void setExposeProxy(boolean exposeProxy);

	/**
	 * 判断代理对象是否被设置到了AOP框架中的ThreadLocal中
	 */
	boolean isExposeProxy();

	/**
	 * 设置所有添加的advisor是否已经提前过滤过了(advisor和目标对象已经提前匹配过了)
	 * 也就是所添加advisor的Advice已经是完全可以应用到目标对象上的
	 */
	void setPreFiltered(boolean preFiltered);

	/**
	 * 判断所有添加的advisor是否已经提前过滤过了
	 */
	boolean isPreFiltered();

	/**
	 * 返回Advisor列表
	 */
	Advisor[] getAdvisors();

	/**
	 * 添加Advisor
	 */
	void addAdvisor(Advisor advisor) throws AopConfigException;

	/**
	 * 在指定位置添加Advisor
	 */
	void addAdvisor(int pos, Advisor advisor) throws AopConfigException;

	/**
	 * 删除Advisor,不存在的话不做删除
	 */
	boolean removeAdvisor(Advisor advisor);

	/**
	 * 删除指定位置Advisor,index无效的话会报异常
	 */
	void removeAdvisor(int index) throws AopConfigException;

	/**
	 * 返回advisor位置,不存在返回-1
	 */
	int indexOf(Advisor advisor);

	/**
	 * 用新的advisor替换旧的advisor(b替换a)
	 * <p><b>Note:</b>如果旧advisor实现了接口{@link org.springframework.aop.IntroductionAdvisor}
	 * 会将旧advisor的父类接口从配置interfaces中删除,List<Class> interfaces是Advised的属性(在子类:AdvisedSupport)
	 */
	boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;

	/**
	 * 添加Advice
	 */
	void addAdvice(Advice advice) throws AopConfigException;

	/**
	 * 在指定位置添加advice,对应创建Advisor(类型为:DefaultPointcutAdvisor)
	 * DefaultPointcutAdvisor里面的pointcut为Pointcut.TRUE,和目标对象总是匹配的
	 */
	void addAdvice(int pos, Advice advice) throws AopConfigException;

	/**
	 * 删除advice,成功返回true,失败返回false(对应的Advisor也被删除)
	 */
	boolean removeAdvice(Advice advice);

	/**
	 * 返回advice位置,不存在返回-1
	 */
	int indexOf(Advice advice);

	/**
	 * 返回Advised的配置信息,等效toString(),内部一般是调用toString方法
	 */
	String toProxyConfigString();

}
ProxyConfig是个代理配置管理类,对代理配置进行设置
package org.springframework.aop.framework;

import java.io.Serializable;

import org.springframework.util.Assert;

public class ProxyConfig implements Serializable {

	/** use serialVersionUID from Spring 1.2 for interoperability */
	private static final long serialVersionUID = -8409359707199703185L;


	private boolean proxyTargetClass = false;

	private boolean optimize = false;

	boolean opaque = false;

	boolean exposeProxy = false;

	private boolean frozen = false;


	/**
	 * 设置是否直接代理目标类,而不是目标类的父接口
	 * Spring中代理分为JDK动态代理、CGLIB代理;JDK动态代理是接口,CGLIB代理是目标类(具体类)
	 */
	public void setProxyTargetClass(boolean proxyTargetClass) {
		this.proxyTargetClass = proxyTargetClass;
	}

	/**
	 * 判断是否直接代理的目标类,而不是目标类的父接口
	 * Spring中代理分为JDK动态代理、CGLIB代理;JDK动态代理是接口,CGLIB代理是目标类(具体类)
	 */
	public boolean isProxyTargetClass() {
		return this.proxyTargetClass;
	}

	/**
	 * 设置是否进行优化
	 */
	public void setOptimize(boolean optimize) {
		this.optimize = optimize;
	}

	/**
	 * 判断是否进行优化
	 */
	public boolean isOptimize() {
		return this.optimize;
	}

	/**
	 * Spring AOP在生成代理对象时,默认为代理对象添加接口Advised。
	 * opaque如果为true,则不会添加,举例:
	 * interface IService{}
	 * class A implements IService{},
	 *
	 * 如果opaque为false:
	 *  A生成的代理对象为:Proxy.newProxyInstance(ClassLoader, new Class[]{Advised.class, IService.class}, InvocationHandler);
	 *  如果opaque为true:
	 *  A生成的代理对象为:Proxy.newProxyInstance(ClassLoader, new Class[]{IService.class}, InvocationHandler);
	 */
	public void setOpaque(boolean opaque) {
		this.opaque = opaque;
	}

	/**
	 * 判断是否阻止为创建的代理对象添加接口Advised
	 */
	public boolean isOpaque() {
		return this.opaque;
	}

	/**
	 * 将代理对象是否设置到AOP框架中的ThreadLocal中
	 */
	public void setExposeProxy(boolean exposeProxy) {
		this.exposeProxy = exposeProxy;
	}

	/**
	 * 判断代理对象是否被设置到了AOP框架中的ThreadLocal中
	 */
	public boolean isExposeProxy() {
		return this.exposeProxy;
	}

	/**
	 * 设置advised配置是否冻结
	 *  一旦冻结,不允许删除或增加Advisor和Adivce
	 */
	public void setFrozen(boolean frozen) {
		this.frozen = frozen;
	}

	/**
	 * 判断advised配置是否冻结
	 * 一旦冻结,不允许删除或增加Advisor和Adivce
	 */
	public boolean isFrozen() {
		return this.frozen;
	}


	/**
	 * 复制代理配置内容
	 */
	public void copyFrom(ProxyConfig other) {
		Assert.notNull(other, "Other ProxyConfig object must not be null");
		this.proxyTargetClass = other.proxyTargetClass;
		this.optimize = other.optimize;
		this.exposeProxy = other.exposeProxy;
		this.frozen = other.frozen;
		this.opaque = other.opaque;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("proxyTargetClass=").append(this.proxyTargetClass).append("; ");
		sb.append("optimize=").append(this.optimize).append("; ");
		sb.append("opaque=").append(this.opaque).append("; ");
		sb.append("exposeProxy=").append(this.exposeProxy).append("; ");
		sb.append("frozen=").append(this.frozen);
		return sb.toString();
	}

}
类AdvisedSupport对接口Advised中的方法做了具体实现
类ProxyCreatorSupport对接口ProxyConfig中的方法做了具体实现
ProxyFactory: 根据上面的配置,创建代理对象
package org.springframework.aop.framework;

import org.aopalliance.intercept.Interceptor;

import org.springframework.aop.TargetSource;
import org.springframework.util.ClassUtils;

public class ProxyFactory extends ProxyCreatorSupport {

	/**
	 * 无参构造函数
	 */
	public ProxyFactory() {
	}

	/**
	 * 根据被代理目标类对象创建ProxyFactory
	 * @param target
	 */
	public ProxyFactory(Object target) {
		setTarget(target);
		//获取被代理目标类对象上的接口,设置为被代理接口
		setInterfaces(ClassUtils.getAllInterfaces(target));
	}

	/**
	 * 根据被代理接口Class创建ProxyFactory
	 * @param proxyInterfaces
	 */
	public ProxyFactory(Class<?>... proxyInterfaces) {
		setInterfaces(proxyInterfaces);
	}

	/**
	 * 根据被代理接口Class、Advice创建ProxyFactory
	 * @param proxyInterface
	 * @param interceptor
	 */
	public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
		addInterface(proxyInterface);
		addAdvice(interceptor);
	}

	/**
	 * 根据被代理接口Class、被代理目标类对象(被封装在TargetSource中)创建ProxyFactory
	 * @param proxyInterface
	 * @param targetSource
	 */
	public ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) {
		addInterface(proxyInterface);
		setTargetSource(targetSource);
	}

	/**
	 * 创建代理对象,关键入口
	 * 源码分析:节点1
	 * @return
	 */
	public Object getProxy() {
		//createAopProxy(),源码分析:节点2,具体实现位于父类ProxyCreatorSupport.createAopProxy()
		return createAopProxy().getProxy();
	}

	/**
	 * 创建代理对象
	 * @param classLoader
	 * 		类加载器
	 * @return
	 */
	public Object getProxy(ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

	/**
	 * 创建代理对象
	 * @param proxyInterface
	 * 		被代理的接口
	 * @param interceptor
	 * 		Advice对象
	 * @return
	 */
	public static <T> T getProxy(Class<T> proxyInterface, Interceptor interceptor) {
		return (T) new ProxyFactory(proxyInterface, interceptor).getProxy();
	}

	/**
	 * 创建代理对象
	 * @param proxyInterface
	 * 		被代理的接口
	 * @param targetSource
	 * 		被代理的目标类对象(被封装在TargetSource中)
	 * @return
	 */
	public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {
		return (T) new ProxyFactory(proxyInterface, targetSource).getProxy();
	}

	/**
	 * 创建代理对象
	 * @param targetSource
	 * 		被代理的目标类对象(被封装在TargetSource中)
	 * @return
	 */
	public static Object getProxy(TargetSource targetSource) {
		if (targetSource.getTargetClass() == null) {
			throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class");
		}
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTargetSource(targetSource);
		//采用直接代理目标类(cglib)方式
		proxyFactory.setProxyTargetClass(true);
		return proxyFactory.getProxy();
	}

}
package org.springframework.aop.framework;

import java.util.LinkedList;
import java.util.List;

import org.springframework.util.Assert;

public class ProxyCreatorSupport extends AdvisedSupport {

	//Aop代理工厂,从继承关系上看和ProxyFactory没有关系
	private AopProxyFactory aopProxyFactory;

	private List<AdvisedSupportListener> listeners = new LinkedList<AdvisedSupportListener>();

	//标记AopProxy对象是否已经创建,AopProxy是真正创建代理的类。
	private boolean active = false;


	/**
	 * 无参构造函数
	 * 	核心代码,里面创建this.aopProxyFactory = new DefaultAopProxyFactory();
	 */
	public ProxyCreatorSupport() {
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}
	
	public ProxyCreatorSupport(AopProxyFactory aopProxyFactory) {
		this.aopProxyFactory = aopProxyFactory;
	}
	
	public void setAopProxyFactory(AopProxyFactory aopProxyFactory) {
		this.aopProxyFactory = aopProxyFactory;
	}
	
	public AopProxyFactory getAopProxyFactory() {
		return this.aopProxyFactory;
	}
	
	public void addListener(AdvisedSupportListener listener) {
		this.listeners.add(listener);
	}
	
	public void removeListener(AdvisedSupportListener listener) {
		this.listeners.remove(listener);
	}


	/**
	 * 源码分析:节点2
	 * @return
	 */
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		//源码分析:节点3
		//getAopProxyFactory()默认构造函数创建的aopProxyFactory= new DefaultAopProxyFactory()
		//aopProxyFactory.createAopProxy()创建AopProxy
		return getAopProxyFactory().createAopProxy(this);
	}
	
	private void activate() {
		this.active = true;
		for (AdvisedSupportListener listener : this.listeners) {
			listener.activated(this);
		}
	}
	
	@Override
	protected void adviceChanged() {
		super.adviceChanged();
		synchronized (this) {
			if (this.active) {
				for (AdvisedSupportListener listener : this.listeners) {
					listener.adviceChanged(this);
				}
			}
		}
	}
	
	protected final synchronized boolean isActive() {
		return this.active;
	}

}
package org.springframework.aop.framework;

import java.io.Serializable;

import org.springframework.aop.SpringProxy;

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

	//源码分析:节点3
	//创建AopProxy对象,分为:JdkDynamicAopProxy和CglibAopProxy
	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()) {
                //源码分析:节点4
				//创建JDK动态代理
				return new JdkDynamicAopProxy(config);
			}
			return CglibProxyFactory.createCglibProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
	
	private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
		Class[] interfaces = config.getProxiedInterfaces();
		return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
	}
	
	private static class CglibProxyFactory {

		public static AopProxy createCglibProxy(AdvisedSupport advisedSupport) {
			return new CglibAopProxy(advisedSupport);
		}
	}

}

以JDK动态代理为例:

package org.springframework.aop.framework;

import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.aop.AopInvocationException;
import org.springframework.aop.RawTargetAccess;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

	/** use serialVersionUID from Spring 1.2 for interoperability */
	private static final long serialVersionUID = 5531744639992436476L;

	private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);

	//advised配置对象
	private final AdvisedSupport advised;

	//是否有equals方法
	private boolean equalsDefined;

	//是否有hashCode方法
	private boolean hashCodeDefined;

	/**
	 * 构造函数
	 *
	 * @param config
	 * 		advised配置对象
	 */
	public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
		Assert.notNull(config, "AdvisedSupport must not be null");
		if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
			throw new AopConfigException("No advisors and no TargetSource specified");
		}
		this.advised = config;
	}

	//获取代理对象,核心代码
	public Object getProxy() {
		return getProxy(ClassUtils.getDefaultClassLoader());
	}

	//源码分析:节点4
	//获取代理对象,核心代码
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
		}
		//从配置advised中获取被代理的接口
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		//创建代理对象
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}
	
	//为equalsDefined和hashCodeDefined赋值
	private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
		for (Class<?> proxiedInterface : proxiedInterfaces) {
			Method[] methods = proxiedInterface.getDeclaredMethods();
			for (Method method : methods) {
				if (AopUtils.isEqualsMethod(method)) {
					this.equalsDefined = true;
				}
				if (AopUtils.isHashCodeMethod(method)) {
					this.hashCodeDefined = true;
				}
				if (this.equalsDefined && this.hashCodeDefined) {
					return;
				}
			}
		}
	}


	//源码分析:节点5
	//JDK动态代理接口InvocationHandler固定方法,每次调用目标类方法时,先执行该方法。
	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)) {
				return equals(args[0]);
			}
			if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				return hashCode();
			}
			if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;

			if (this.advised.exposeProxy) {
				//将代理对象proxy放入TreadLocal中
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			//获取目标对象
			target = targetSource.getTarget();
			if (target != null) {
				targetClass = target.getClass();
			}

            //源码分析:节点6
			// 从配置advised中获取所有的Advice
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
			
			if (chain.isEmpty()) { //advice列表为空,直接执行目标类的目标方法
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
			}
			else {
				//源码分析:节点7
				//匹配且挨个执行Advice
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				retVal = invocation.proceed();
			}
			
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				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);
			}
		}
	}
	
	@Override
	public boolean equals(Object other) {
		if (other == this) {
			return true;
		}
		if (other == null) {
			return false;
		}

		JdkDynamicAopProxy otherProxy;
		if (other instanceof JdkDynamicAopProxy) {
			otherProxy = (JdkDynamicAopProxy) other;
		}
		else if (Proxy.isProxyClass(other.getClass())) {
			InvocationHandler ih = Proxy.getInvocationHandler(other);
			if (!(ih instanceof JdkDynamicAopProxy)) {
				return false;
			}
			otherProxy = (JdkDynamicAopProxy) ih;
		}
		else {
			// Not a valid comparison...
			return false;
		}

		// If we get here, otherProxy is the other AopProxy.
		return AopProxyUtils.equalsInProxy(this.advised, otherProxy.advised);
	}

	/**
	 * Proxy uses the hash code of the TargetSource.
	 */
	@Override
	public int hashCode() {
		return JdkDynamicAopProxy.class.hashCode() * 13 + this.advised.getTargetSource().hashCode();
	}

}
总结一下调用链路:
ProxyFactory===创建===》AopProxyFactory(默认实现:DefaultAopProxyFactory)===创建===》AopProxy(JdkDynamicAopProxy||CglibAopProxy)
AopProxy完成代理对象创建和调用。

============================================================

源码分析:节点6,AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice==》
AdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice,进入到DefaultAdvisorChainFactory
package org.springframework.aop.framework;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.aopalliance.intercept.Interceptor;
import org.aopalliance.intercept.MethodInterceptor;

import org.springframework.aop.Advisor;
import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.framework.AdvisorChainFactory;
import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.aop.support.MethodMatchers;

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {

	//获取匹配的Advice列表
	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, Class targetClass) {
		List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
		boolean hasIntroductions = hasMatchingIntroductions(config, targetClass);
		//里面注册着Advisor适配器,例如:ThrowsAdvice类型的会被转为ThrowsAdviceInterceptor
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
		for (Advisor advisor : config.getAdvisors()) {
			if (advisor instanceof PointcutAdvisor) {
				// 从Advised配置中获取Advisor
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				// 获取ClassFilter过滤类
				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(targetClass)) {
					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
					// 获取MethodMatcher过滤方法
					if (MethodMatchers.matches(mm, method, targetClass, hasIntroductions)) {
						if (mm.isRuntime()) {
							for (MethodInterceptor interceptor : interceptors) { //如果是动态匹配,包装一层InterceptorAndDynamicMethodMatcher
								interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
							}
						}
						else {
							interceptorList.addAll(Arrays.asList(interceptors));
						}
					}
				}
			}
			else if (advisor instanceof IntroductionAdvisor) { //如果是引介增强,只需要过滤类
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (config.isPreFiltered() || ia.getClassFilter().matches(targetClass)) {
					Interceptor[] interceptors = registry.getInterceptors(advisor);
					interceptorList.addAll(Arrays.asList(interceptors));
				}
			}
			else {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}
		return interceptorList;
	}

	/**
	 * Determine whether the Advisors contain matching introductions.
	 */
	private static boolean hasMatchingIntroductions(Advised config, Class targetClass) {
		for (int i = 0; i < config.getAdvisors().length; i++) {
			Advisor advisor = config.getAdvisors()[i];
			if (advisor instanceof IntroductionAdvisor) {
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (ia.getClassFilter().matches(targetClass)) {
					return true;
				}
			}
		}
		return false;
	}

}
源码分析:节点7,ReflectiveMethodInvocation#proceed
package org.springframework.aop.framework;

package org.spring.aop.proxyfactory;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.BridgeMethodResolver;

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {

	//代理对象
	protected final Object proxy;

	//目标对象
	protected final Object target;

	//被调方法
	protected final Method method;

	//被掉方法参数
	protected Object[] arguments;

	//目标对象的Class
	private final Class targetClass;

	private Map<String, Object> userAttributes;

	//Advice列表
	protected final List interceptorsAndDynamicMethodMatchers;

	//Advice是个list链,用于记录执行到第几个Advice的下标
	private int currentInterceptorIndex = -1;


	/**
	 * 构造函数
	 *
	 * @param proxy
	 * 		代理对象
	 * @param target
	 * 		目标对象
	 * @param method
	 * 		被调方法
	 * @param arguments
	 * 		被掉方法参数
	 * @param targetClass
	 * 		目标对象的Class
	 * @param interceptorsAndDynamicMethodMatchers
	 * 		Advice列表
	 */
	protected ReflectiveMethodInvocation(
			Object proxy, Object target, Method method, Object[] arguments,
			Class targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {

		this.proxy = proxy;
		this.target = target;
		this.targetClass = targetClass;
		this.method = BridgeMethodResolver.findBridgedMethod(method);
		this.arguments = arguments;
		this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
	}


	public final Object getProxy() {
		return this.proxy;
	}

	public final Object getThis() {
		return this.target;
	}

	public final AccessibleObject getStaticPart() {
		return this.method;
	}

	public final Method getMethod() {
		return this.method;
	}

	public final Object[] getArguments() {
		return (this.arguments != null ? this.arguments : new Object[0]);
	}

	public void setArguments(Object[] arguments) {
		this.arguments = arguments;
	}

    //核心代码
	//执行Advice
    //递归调用Advice
	public Object proceed() throws Throwable {
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { //动态匹配
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else { //动态匹配失败
				return proceed();
			}
		}
		else {//不是动态匹配
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}
	
	protected Object invokeJoinpoint() throws Throwable {
		return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
	}

	
	public MethodInvocation invocableClone() {
		Object[] cloneArguments = null;
		if (this.arguments != null) {
			// Build an independent copy of the arguments array.
			cloneArguments = new Object[this.arguments.length];
			System.arraycopy(this.arguments, 0, cloneArguments, 0, this.arguments.length);
		}
		return invocableClone(cloneArguments);
	}
	
	public MethodInvocation invocableClone(Object[] arguments) {
		// Force initialization of the user attributes Map,
		// for having a shared Map reference in the clone.
		if (this.userAttributes == null) {
			this.userAttributes = new HashMap<String, Object>();
		}

		// Create the MethodInvocation clone.
		try {
			ReflectiveMethodInvocation clone = (ReflectiveMethodInvocation) clone();
			clone.arguments = arguments;
			return clone;
		}
		catch (CloneNotSupportedException ex) {
			throw new IllegalStateException(
					"Should be able to clone object of type [" + getClass() + "]: " + ex);
		}
	}


	public void setUserAttribute(String key, Object value) {
		if (value != null) {
			if (this.userAttributes == null) {
				this.userAttributes = new HashMap<String, Object>();
			}
			this.userAttributes.put(key, value);
		}
		else {
			if (this.userAttributes != null) {
				this.userAttributes.remove(key);
			}
		}
	}

	public Object getUserAttribute(String key) {
		return (this.userAttributes != null ? this.userAttributes.get(key) : null);
	}
	
	public Map<String, Object> getUserAttributes() {
		if (this.userAttributes == null) {
			this.userAttributes = new HashMap<String, Object>();
		}
		return this.userAttributes;
	}


	@Override
	public String toString() {
		// Don't do toString on target, it may be proxied.
		StringBuilder sb = new StringBuilder("ReflectiveMethodInvocation: ");
		sb.append(this.method).append("; ");
		if (this.target == null) {
			sb.append("target is null");
		}
		else {
			sb.append("target is of class [").append(this.target.getClass().getName()).append(']');
		}
		return sb.toString();
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/779841.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从零开始实现大语言模型(四):简单自注意力机制

1. 前言 理解大语言模型结构的关键在于理解自注意力机制(self-attention)。自注意力机制可以判断输入文本序列中各个token与序列中所有token之间的相关性&#xff0c;并生成包含这种相关性信息的context向量。 本文介绍一种不包含训练参数的简化版自注意力机制——简单自注意…

STM32-PWR和WDG看门狗

本内容基于江协科技STM32视频学习之后整理而得。 文章目录 1. PWR1.1 PWR简介1.2 电源框图1.3 上电复位和掉电复位1.4 可编程电压监测器1.5 低功耗模式1.6 模式选择1.7 睡眠模式1.8 停止模式1.9 待机模式1.10 库函数 2. WDG看门狗2.1 WDG简介2.2 IWDG框图2.3 IWDG键寄存器2.4 …

ACM ICPS独立出版 | 2024年第三届计算与人工智能国际会议(ISCAI 2024)

会议简介 Brief Introduction 2024年第三届计算与人工智能国际会议(ISCAI 2024) 会议时间&#xff1a;2024年11月22 -24日 召开地点&#xff1a;中国大理 大会官网&#xff1a;www.iscai.org 2024年第三届计算与人工智能国际会议(ISCAI 2024)将围绕“计算与人工智能”的最新研究…

排序 -- 冒泡排序和快速排序

一、 交换排序 1、基本思想 所谓交换&#xff0c;就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置&#xff0c;交换排序的特点是&#xff1a;将键值较大的记录向序列的尾部移动&#xff0c;键值较小的记录向序列的前部移动。 2、常见的交换排序 1、冒泡…

Java Selenium入门程序

需求&#xff1a;使用chrome浏览器打开百度首页 1.配置浏览器驱动 &#xff08;1&#xff09;下载浏览器驱动&#xff0c;浏览器版本需与驱动版本一致&#xff1b; &#xff08;2&#xff09;编辑系统环境变量-->编辑Path-->填入浏览器驱动路径&#xff1a; 2.maven工…

【反悔贪心 反悔堆】1642. 可以到达的最远建筑

本文涉及知识点 反悔贪心 反悔堆 LeetCode1642. 可以到达的最远建筑 给你一个整数数组 heights &#xff0c;表示建筑物的高度。另有一些砖块 bricks 和梯子 ladders 。 你从建筑物 0 开始旅程&#xff0c;不断向后面的建筑物移动&#xff0c;期间可能会用到砖块或梯子。 当…

刷题之删除有序数组中的重复项(leetcode)

删除有序数组中的重复项 这题简单题&#xff0c;双指针&#xff0c;一个指针记录未重复的数的个数&#xff0c;另一个记录遍历的位置。 以下是简单模拟&#xff0c;可以优化&#xff1a; class Solution { public:int removeDuplicates(vector<int>& nums) {int l0…

STL--求交集,并集,差集(set_intersection,set_union,set_difference)

set_intersection(重要) 求两个有序的序列的交集. 函数声明如下: template<class InputIterator1, class InputIterator2, class OutputIterator>OutputIterator set_intersection(InputIterator1 _First1, //容器1开头InputIterator1 _Last1, //容器2结尾(不包含)Inp…

ChatGPT4深度解析:探索智能对话新境界

大模型chatgpt4分析功能初探 目录 1、探测目的 2、目标变量分析 3、特征缺失率处理 4、特征描述性分析 5、异常值分析 6、相关性分析 7、高阶特征挖掘 1、探测目的 1、分析chat4的数据分析能力&#xff0c;提高部门人效 2、给数据挖掘提供思路 3、原始数据&#xf…

Navicat终于免费了, 但是这个结果很奇葩

个人用下载地址: 点呀 好家伙, 每个机构最多5个用户, 对于正在审计的公司…

DAY1: 实习前期准备

文章目录 VS Code安装的插件C/CCMakeGitHub CopilotRemote-SSH收获 VS Code 下载链接&#xff1a;https://code.visualstudio.com 安装的插件 C/C 是什么&#xff1a;C/C IntelliSense, debugging, and code browsing. 为什么&#xff1a;初步了解如何在VS Code里使用C输出…

Vulnhub-Os-hackNos-1(包含靶机获取不了IP地址)

https://download.vulnhub.com/hacknos/Os-hackNos-1.ova #靶机下载地址 题目&#xff1a;要找到两个flag user.txt root.txt 文件打开 改为NAT vuln-hub-OS-HACKNOS-1靶机检测不到IP地址 重启靶机 按住shift 按下键盘字母"E"键 将图中ro修改成…

筛选Github上的一些优质项目

每个项目旁都有标签说明其特点&#xff0c;如今日热捧、多模态、收入生成、机器人、大型语言模型等。 项目涵盖了不同的编程语言和领域&#xff0c;包括人工智能、语言模型、网页数据采集、聊天机器人、语音合成、AI 代理工具集、语音转录、大型语言模型、DevOps、本地文件共享…

7-6 每日升学消息汇总

复旦附中清北比例大涨&#xff0c;从统计数据来看&#xff0c;今年复附的清北人数将创历史新高&#xff0c;达到前所未有年进43人。离上海7月9号中考出分&#xff0c;还有3天。小道消息说&#xff0c;画狮的数游天下又回来了&#xff0c;目前还未官方消息。2024第二届国际数学夏…

安卓虚拟位置修改1.25beta支持路线模拟、直接定位修改

导语:更新支持安卓14/15&#xff0c;支持路线模拟、直接定位修改&#xff0c;仅支持单一版本 无root需根据教程搭配下方链接所提供的虚拟机便可进行使用 有root且具备XP环境可直接真机运行 如你有特殊需求 重启问题设置打开XP兼容 针对具有虚拟机检测的软件 建议如下 度娘搜索…

多表查询sql

概述&#xff1a;项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系&#xff0c;分为三种&#xff1a; 一对多多对多一对一 一、多表关系 一对多 案例&#xff1a;部门与…

在CMD中创建虚拟环境并在VSCode中使用和管理

1. 使用Conda创建虚拟环境 在CMD或Anaconda Prompt中执行以下代码以创建一个新的虚拟环境&#xff1a; conda create -n my_env python 3.8 这样会创建一个名为 my_env 的环境&#xff0c;并在Anaconda环境目录下生成一个相应的文件夹&#xff0c;包含该虚拟环境所需的所有…

STM32-ADC+DMA

本内容基于江协科技STM32视频学习之后整理而得。 文章目录 1. ADC模拟-数字转换器1.1 ADC模拟-数字转换器1.2 逐次逼近型ADC1.3 ADC框图1.4 ADC基本结构1.5 输入通道1.6 规则组的转换模式1.6.1 单次转换&#xff0c;非扫描模式1.6.2 连续转换&#xff0c;非扫描模式1.6.3 单次…

时间、查找、打包、行过滤与指令的运行——linux指令学习(二)

前言&#xff1a;本节内容标题虽然为指令&#xff0c;但是并不只是讲指令&#xff0c; 更多的是和指令相关的一些原理性的东西。 如果友友只想要查一查某个指令的用法&#xff0c; 很抱歉&#xff0c; 本节不是那种带有字典性质的文章。但是如果友友是想要来学习的&#xff0c;…

如何确保 PostgreSQL 在高并发写操作场景下的数据完整性?

文章目录 一、理解数据完整性二、高并发写操作带来的挑战三、解决方案&#xff08;一&#xff09;使用合适的事务隔离级别&#xff08;二&#xff09;使用合适的锁机制&#xff08;三&#xff09;处理死锁&#xff08;四&#xff09;使用索引和约束&#xff08;五&#xff09;批…