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 {@Overridepublic 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) {//创建pointcutAspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();pointcut.setExpression(expression);//创建adviceLogAdvice advice = new LogAdvice();//创建advisorAdvisor 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;}@Overridepublic 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()创建AopProxyreturn getAopProxyFactory().createAopProxy(this);}private void activate() {this.active = true;for (AdvisedSupportListener listener : this.listeners) {listener.activated(this);}}@Overrideprotected 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和CglibAopProxypublic 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中获取所有的AdviceList<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);if (chain.isEmpty()) { //advice列表为空,直接执行目标类的目标方法retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);}else {//源码分析:节点7//匹配且挨个执行Adviceinvocation = 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);}}}@Overridepublic 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.*/@Overridepublic 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类型的会被转为ThrowsAdviceInterceptorAdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();for (Advisor advisor : config.getAdvisors()) {if (advisor instanceof PointcutAdvisor) {// 从Advised配置中获取AdvisorPointcutAdvisor 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) { //如果是动态匹配,包装一层InterceptorAndDynamicMethodMatcherinterceptorList.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;//目标对象的Classprivate 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//递归调用Advicepublic 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;}@Overridepublic 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.mzph.cn/pingmian/41565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

H5 Canvas实现转盘效果,控制指定数字

效果图 实现思路&#xff1a; 用Canvas画圆&#xff0c;然后再画扇形&#xff0c;然后中奖的开始用一张图片代替&#xff0c;点击的时候触发转动效果。 实现代码&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8"><tit…

MQ:RabbitMQ

同步和异步通讯 同步通讯: 需要实时响应,时效性强 耦合度高 每次增加功能都要修改两边的代码 性能下降 需要等待服务提供者的响应,如果调用链过长则每次响应时间需要等待所有调用完成 资源浪费 调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下…

排序——交换类排序、插入类排序、选择类排序、归并类排序

排序 排序算法分为交换类排序、插入类排序、选择类排序、归并类排序。 交换类排序 冒泡排序 冒泡排序的基本思想是&#xff1a;从后往前&#xff08;或从前往后&#xff09;两两比较相邻元素的值。若A[ j - 1 ] > A[ j ]&#xff0c;则交换它们&#xff0c;直到序列比较…

commonjs、module 模块同时启动

怎样同时在一个项目中同时启动node服务和我们前端项目&#xff08;commonjs、module 模块同时启动&#xff09; 今天在使用node实现完增删改查的接口之后&#xff0c;将自己node代码嵌入到我们react项目中 启动完前端项目之后&#xff0c;当我使用node service.js的时候&#x…

Unity 简单载具路线 Waypoint 导航

前言 在游戏开发和导航系统中&#xff0c;"waypoint" 是指路径中的一个特定位置或点。它通常用于定义一个物体或角色在场景中移动的目标位置或路径的一部分。通过一系列的 waypoints&#xff0c;可以指定复杂的移动路径和行为。以下是一些 waypoint 的具体用途&…

用Python轻松转换PDF为CSV

数据的可访问性和可操作性是数据管理的核心要素。PDF格式因其跨平台兼容性和版面固定性&#xff0c;在文档分享和打印方面表现出色&#xff0c;尤其适用于报表、调查结果等数据的存储。然而&#xff0c;PDF的非结构化特性限制了其在数据分析领域的应用。相比之下&#xff0c;CS…

【国产开源可视化引擎Meta2d.js】图元

图元 又称画笔Pen。图形表达的基本元素&#xff0c;组成图像的基本单元。 构成 每一个图元由ID、名字、类型、属性&#xff08;数据&#xff09;组成。 ID 名为“id”的特殊属性&#xff0c;图元实例&#xff08;画布上的图元对象&#xff09;的唯一标识。拖拽到画布或创建…

【线性代数的本质】矩阵与线性变换

线性变化要满足两点性质&#xff1a; 直线&#xff08;连续的点&#xff09;在变换后还是直线。原点不变。 假设有坐标轴&#xff08;基底&#xff09; i ^ \widehat{i} i 和 j ^ \widehat{j} j ​&#xff1a; i ^ [ 1 0 ] , j ^ [ 0 1 ] \widehat{i}\begin{bmatrix} 1 \…

《昇思25天学习打卡营第6天|网络构建》

文章目录 前言&#xff1a;今日所学&#xff1a;1. 定义模型类2. 模型层3. 模型参数 前言&#xff1a; 在第六节中我们学习了网络构建&#xff0c;了解了神经网络模型是由神经网络层和Tensor操作构成&#xff0c;我们使用的mindspore.nn中提供了常见的升级网络层的实现&#x…

在线图片转文字的软件,分享3种强大的软件!

在信息爆炸的时代&#xff0c;图片作为信息的重要载体之一&#xff0c;其内容往往蕴含着巨大的价值。然而&#xff0c;面对海量的图片信息&#xff0c;如何高效、准确地将其转化为文字&#xff0c;成为了许多人的迫切需求。今天&#xff0c;就为大家盘点几款功能强大的在线图片…

【python基础】—如何理解安装程序时要配置Widows和DOS操作系统中的path环境变量?

文章目录 前言一、环境变量是什么&#xff1f;二、为什么需要设置环境变量&#xff1f;三、配置anaconda的环境变量 前言 在安装一些程序的时候&#xff0c; 我们总是需要将安装路径配置到正在使用电脑的环境变量里。为什么要进行这一步呢&#xff1f;本文主要解释Widows和DOS…

特殊用途二极管+二极管故障检测+三极管(BJT)的工作原理+定时器的使用(小灯定时闪烁实现)

2024-7-5&#xff0c;星期五&#xff0c;17:27&#xff0c;天气&#xff1a;晴&#xff0c;心情&#xff1a;晴。今天没有什么特殊的事情发生&#xff0c;继续学习啦&#xff0c;加油加油&#xff01;&#xff01;&#xff01; 今日完成模电自选教材第二章内容的学习&#xff…

1-4 NLP发展历史与我的工作感悟

1-4 NLP发展历史与我的工作感悟 主目录点这里 第一个重要节点&#xff1a;word2vec词嵌入 能够将无限的词句表示为有限的词向量空间&#xff0c;而且运算比较快&#xff0c;使得文本与文本间的运算有了可能。 第二个重要节点&#xff1a;Transformer和bert 为预训练语言模型发…

【ABB】原点设定

【ABB】原点设定 操作流程演示 操作流程 操作轴回原点编辑电机校准偏移更新转速计数器 1.首先得了解机器手的轴&#xff0c;这里以6轴作参考。 注意先回456轴&#xff0c;后回123轴。 2.然后需要了解机器人关节运动模式&#xff0c;即选择如下两个模式。 3.注意机器人各轴移动…

QT的编译过程(底层逻辑)

qmake -project 用于从源代码生成项目文件&#xff0c;qmake 用于从项目文件生成 Makefile&#xff0c;而 make 用于根据 Makefile 构建项目。 详细解释&#xff1a; qmake -project 这个命令用于从源代码目录生成一个初始的 Qt 项目文件&#xff08;.pro 文件&#xff09;。它…

吃顿饭的时间,用AI开发一个应用官网

最早接触开发时做的第一个项目就是企业官网&#xff0c;到后来自己开始走上独立开发者的道路时&#xff0c;哪怕是开发面向消费者的移动端产品&#xff0c;在产品上架时也需要提供应用官网。 感觉&#xff0c;编程这件事情和官网开发&#xff0c;紧密相连。 过往为了追求开发效…

个人微信 微信营销系统

个人微信 微信营销系统 CRM系统

Windows 玩转大模型第一天:大模型本地部署,调用大模型API可直接工程化应用(全部代码和详细部署流程)

Ollama 是一个开源框架&#xff0c;专为在本地机器上便捷部署和运行大型语言模型&#xff08;LLM&#xff09;而设计。 以下是其主要特点和功能概述&#xff1a; 1. 简化部署&#xff1a;Ollama 目标在于简化在 Docker 容器中部署大型语言模型的过程&#xff0c;使得非专业用…

ELK日志系统和Filebeat采集器的学习总结

ELK是ElasticSerach、Logstash、Kina Logstash负责采集数据&#xff0c;Logstash有三个插件&#xff0c;input、filter、output&#xff0c;filter插件作用是对采集的数据进行处理&#xff0c;过滤的&#xff0c;因此filter插件可以选&#xff0c;可以不用配置。 ElasticSear…

vulnhub靶场之DC-1

1 信息收集 1.1 主机发现 arp-scan -l 主机ip地址为&#xff1a;192.168.1.4 1.2 端口服务扫描 nmap -sS -sV -A -T5 -p- 192.168.1.4 开发22&#xff0c;80&#xff0c;111端口 1.3 目录扫描 dirsearch -u 192.168.1.4 2 渗透测试 2.1 先访问一下80端口 发现是一个…