本篇内容介绍了“spring中代理的创建方法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
spring 中创建代理使用了 Jdk 和 Cglib 两种方式创建,JdkDynamicAopProxy
和 ObjenesisCglibAopProxy
,通过使用配置 Advised
和 ProxyConfig
来管理配置,根据配置决定使用哪种方式创建代理,下面来介绍这几个关键的类。
Advised 是一个管理 AOP 代理工厂配置的接口,在spring中的所有AopProxy都可以转换为 Advised。
在 spring 中,使用 ProxyConfig
来配置代理创建属性。
/** * 代理工厂的超类,用于统一管理代理工厂类的属性。 */ public class ProxyConfig implements Serializable { // true:使用子类代理,false:使用接口代理 private boolean proxyTargetClass = false; // 启动代理优化 private boolean optimize = false; // 使用该代理工长创建的代理是否可以转换为 Advised,默认为false:表示可以, // 如果为false,可以将bean转换为Advised:Advised testBean = (Advised) context.getBean("testBean"); boolean opaque = false; // 将代理暴露出去,绑定到 ThreadLocal 的 currentProxy,用于代理类自己的方法调用自己的场景。 boolean exposeProxy = false; // 冻结配置,true:不能修改该代理工长的配置。 private boolean frozen = false; }
实现了ProxyConfig
的直接子类有4个:
ScopedProxyFactoryBean、ProxyProcessorSupport、AbstractSingletonProxyFactoryBean、AdvisedSupport
,这几个类使用不同的方式来创建代理,但是最后还是会将创建代理的工作委托给 ProxyFactory
,下面来查看4个直接子类的相关代码。
ScopedProxyFactoryBean
:用于@Scope 注解,实现bean的作用域控制。他实现了 BeanFactory
、BeanFactoryAware
接口,具有创建、管理bean的能力。
这个类生成的代理只会记录类的名称,然后根据作用域获取bean,如果是prototype的,则beanFactory会创建一个新的bean。
public class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean<Object>, BeanFactoryAware, AopInfrastructureBean{ // 使用它来管理bean的作用域,他的实现很简答,就是获取对象时,委托给 beanFactory,然后 beanFactory 根据作用域获取对应的bean。 private final SimpleBeanTargetSource scopedTargetSource = new SimpleBeanTargetSource(); @Override public void setBeanFactory(BeanFactory beanFactory) { if (!(beanFactory instanceof ConfigurableBeanFactory)) { throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory); } ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory; // 将beanFactory 与 scopedTargetSource 关联,获取代理目标类时,从 scopedTargetSource 中获取, // SimpleBeanTargetSource 将获取bean的操作委托给了beanFactory this.scopedTargetSource.setBeanFactory(beanFactory); ProxyFactory pf = new ProxyFactory(); pf.copyFrom(this); pf.setTargetSource(this.scopedTargetSource); Assert.notNull(this.targetBeanName, "Property 'targetBeanName' is required"); Class<?> beanType = beanFactory.getType(this.targetBeanName); if (beanType == null) { throw new IllegalStateException("Cannot create scoped proxy for bean '" + this.targetBeanName + "': Target type could not be determined at the time of proxy creation."); } // 使用接口代理 if (!isProxyTargetClass() || beanType.isInterface() || Modifier.isPrivate(beanType.getModifiers())) { pf.setInterfaces(ClassUtils.getAllInterfacesForClass(beanType, cbf.getBeanClassLoader())); } // 简单的代理增强,在调用代理类时,从 beanFactory 中获取bean进行调用,这样就做到作用域的控制了。 ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName()); pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject)); // 标记代理需要不需要被AOP拦截,及时有切入点匹配 pf.addInterface(AopInfrastructureBean.class); // 创建代理对像:将创建代理交给 ProxyFactory this.proxy = pf.getProxy(cbf.getBeanClassLoader()); } }
ProxyProcessorSupport
:为 ProxyFactory
提供了常用的公共方法。
public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean { /** * 可以自定义排序 */ public void setOrder(int order) { this.order = order; } @Override public int getOrder() { return this.order; } /** * 当实现了接口时,使用接口代理,没有实现接口则使用类代理。 */ protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) { Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader()); boolean hasReasonableProxyInterface = false; for (Class<?> ifc : targetInterfaces) { if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) && ifc.getMethods().length > 0) { hasReasonableProxyInterface = true; break; } } if (hasReasonableProxyInterface) { for (Class<?> ifc : targetInterfaces) { proxyFactory.addInterface(ifc); } } else { proxyFactory.setProxyTargetClass(true); } } }
AbstractSingletonProxyFactoryBean
: 创建单例代理对象,在需要代理的对象实例化后,使用 InitializingBean#afterPropertiesSet()
来创建代理,并为其设置前置通知和后置通知。
public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig implements FactoryBean<Object>, BeanClassLoaderAware, InitializingBean { // 代理目标对象 private Object target; // 需要代理的接口 private Class<?>[] proxyInterfaces; // 前置拦截器 private Object[] preInterceptors; // 后置拦截器 private Object[] postInterceptors; // 全局 Advisor 注册器 private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance(); // 类加载器 private transient ClassLoader proxyClassLoader; // 代理对象 private Object proxy; // 实例化之后调用 @Override public void afterPropertiesSet() { // .... // 将代理创建工作委托给 ProxyFactory ProxyFactory proxyFactory = new ProxyFactory(); // 将预处理器、主处理器、后置处理器按顺序添加,可以组成一个处理器链根据添加顺序来执行所有的处理器。 // 添加预处理器 if (this.preInterceptors != null) { for (Object interceptor : this.preInterceptors) { proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor)); } } // 添加主要的处理器,交给子类实现 proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor())); // 添加后置处理器 if (this.postInterceptors != null) { for (Object interceptor : this.postInterceptors) { proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor)); } } // 复制属性 proxyFactory.copyFrom(this); // 创建代理目标源:默认是 SingletonTargetSource TargetSource targetSource = createTargetSource(this.target); proxyFactory.setTargetSource(targetSource); // 设置代理的接口 if (this.proxyInterfaces != null) { proxyFactory.setInterfaces(this.proxyInterfaces); } // 如果没有使用类代理的方式,解析目标类的接口。 else if (!isProxyTargetClass()) { // Rely on AOP infrastructure to tell us what interfaces to proxy. Class<?> targetClass = targetSource.getTargetClass(); if (targetClass != null) { proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } } // 代理工厂后置处理方法,由子类实现,更改代理配置 postProcessProxyFactory(proxyFactory); // 创建代理对象,委托给了 ProxyFactory this.proxy = proxyFactory.getProxy(this.proxyClassLoader); } }
AdvisedSupport
:实现了 Advised
,将 ProxyConfig
与 Advised
进行适配,为 Advised
提供了支持,他的唯一子类 ProxyCreatorSupport
为创建代理提供了支持。
public class AdvisedSupport extends ProxyConfig implements Advised { // 空代理对象 public static final TargetSource EMPTY_TARGET_SOURCE = EmptyTargetSource.INSTANCE; // 代理目标源:默认为空目标源 TargetSource targetSource = EMPTY_TARGET_SOURCE; // 是否已经对Advisors进行了过虑 private boolean preFiltered = false; // Advisor 调用链工长 AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory(); // 缓存方法对应的 Advisor 调用链。 private transient Map<MethodCacheKey, List<Object>> methodCache; // 要实现的代理接口,按顺序存储。 private List<Class<?>> interfaces = new ArrayList<>(); // Advisor 列表 private List<Advisor> advisors = new ArrayList<>(); // Advisor 数据,为了方便内部操作。 private Advisor[] advisorArray = new Advisor[0]; }
ProxyCreatorSupport
为创建代理提供了支持,他使用了AopProxyFactory
来创建AopProxy
,最后ProxyFactory
使用 AopProxy
来创建代理对象。
在创建ProxyCreatorSupport
时默认创建 DefaultAopProxyFactory
,由他来判断使用接口代理还是子类代理。
public class ProxyCreatorSupport extends AdvisedSupport { private AopProxyFactory aopProxyFactory; private final List<AdvisedSupportListener> listeners = new LinkedList<>(); // 在创建第一个代理后将置为true,表示进入活动状态,将会触发 listeners。 private boolean active = false; /** * 无参构造器,将会创建一个默认的aopProxyFactory。 * DefaultAopProxyFactory 是一个创建代理的工长,用于根据配置创建代理。 */ public ProxyCreatorSupport() { this.aopProxyFactory = new DefaultAopProxyFactory(); } // 创建AOP代理,根据自身的配置属性觉得使用JDK代理还是Cglib代理。 protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); } }
上面提到使用 DefaultAopProxyFactory
来决定使用 jdk代理还是 Cglib代理,他通过接收一个 AdvisedSupport
// AopProxy 工厂 public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { @Override 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."); } // 代理目标是接口,或者也是一个代理对象,使用jdk代理,否则使用Cglib 代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } // 使用接口代理:JDK代理 else { return new JdkDynamicAopProxy(config); } } }
ProxyFactory
是ProxyCreatorSupport
的子类,通过调用父类的方法获取AopProxy
来创建目标代理对象。
public class ProxyFactory extends ProxyCreatorSupport { public Object getProxy() { // 掉用 `ProxyCreatorSupport#createAopProxy` 方法之后根据配置来判断使用 JDK生成代理还是 Cglib生成代理 return createAopProxy().getProxy(); } // 与上面的方法区别在于传入了类加载器 public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); } }
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable { /** 代理配置. */ private final AdvisedSupport advised; /** * 代理的接口上是否定义了equals方法 */ private boolean equalsDefined; /** * 代理的接口是否定义了hashCode 方法 */ private boolean hashCodeDefined; 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; } // 创建代理 @Override public Object getProxy() { // 传入默认类加载器 return getProxy(ClassUtils.getDefaultClassLoader()); } @Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource()); } // 获取代理目标类的所有接口 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); // 检查接口是否实现了equals 和 hashCode 方法 findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); // 创建代理对象,这里传入了this对象,因为 JdkDynamicAopProxy 实现了 InvocationHandler,使用这一段代理逻辑进行代理 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); } /** * aop代理使用jdk代理将执行的逻辑 */ @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 { // 执行equals方法时,接口未定义 equals 方法 ,执行JdkDynamicAopProxy 的 equals 方法 if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { return equals(args[0]); } // 执行 hashCode 方法时,接口未定义 hashCode 方法,执行JdkDynamicAopProxy的hashCode方法 else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { return hashCode(); } // else if (method.getDeclaringClass() == DecoratingProxy.class) { return AopProxyUtils.ultimateTargetClass(this.advised); } // 能够转换为Advised,将转换为Advised,然后执行 else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } Object retVal; // 是否暴露当前的代理,绑定到ThreadLocal中, if (this.advised.exposeProxy) { oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // 获取目标对象 target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); // 根据代理目标对象和方法获取切入点、方法拦截器等。 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); // 如果与该方法匹配的拦截器或通知为空,则进行直接调用,避免创建MethodInvocation if (chain.isEmpty()) { // 找到方法 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); // 直接调用原始对象方法 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { // 调用 切入点、方法拦截器,目标类 MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); retVal = invocation.proceed(); } // Class<?> returnType = method.getReturnType(); // 如果返回值是目标对象,并且代理对象是返回值类型的一个实例,则将返回值替换为代理对象 // 方法的声明类未实现 RawTargetAccess if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { retVal = proxy; } // 如果返回值类型时基础数据类型,并且为null。 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()) { targetSource.releaseTarget(target); } if (setProxyContext) { AopContext.setCurrentProxy(oldProxy); } } } }
在 JdkDynamicAopProxy
中,有2处关键代码,1是获取代理目标的接口,2是执行切入点、拦截器。
AopProxyUtils#completeProxiedInterfaces()
方法获取代理目标的接口,按照规则添加一部分接口SpringProxy、Advised、DecoratingProxy
。
// AopProxyUtils static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) { // 获取目标类实现的接口接口 Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces(); // 目标类的接口为空 if (specifiedInterfaces.length == 0) { // 获取代理目标class Class<?> targetClass = advised.getTargetClass(); if (targetClass != null) { // 判断目标类型是否是接口 if (targetClass.isInterface()) { advised.setInterfaces(targetClass); } // 代理目标类型是代理 else if (Proxy.isProxyClass(targetClass)) { advised.setInterfaces(targetClass.getInterfaces()); } // 重新获取代理对象的接口集 specifiedInterfaces = advised.getProxiedInterfaces(); } } // 如果目标类未实现 SpringProxy 接口,将添加 SpringProxy 到接口集中。 boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class); // 目标类能转换为Advised,并且未实现 Advised 接口,则添加 Advised 到接口集中 boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class); // decoratingProxy 为true,且目标类未实现 DecoratingProxy 接口,将 DecoratingProxy 添加进接口集中 boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)); // 划分接口数组长度 int nonUserIfcCount = 0; if (addSpringProxy) { nonUserIfcCount++; } if (addAdvised) { nonUserIfcCount++; } if (addDecoratingProxy) { nonUserIfcCount++; } Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount]; // 拷贝 System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length); // 将接口class设置进对应的数组位置 int index = specifiedInterfaces.length; if (addSpringProxy) { proxiedInterfaces[index] = SpringProxy.class; index++; } if (addAdvised) { proxiedInterfaces[index] = Advised.class; index++; } if (addDecoratingProxy) { proxiedInterfaces[index] = DecoratingProxy.class; } // 返回需要代理的接口集。 return proxiedInterfaces; }
执行切面和方法拦截器逻辑 ReflectiveMethodInvocation#proceed
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable { public Object proceed() throws Throwable { // 执行完后通知或拦截器后,将执行业务方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } // 获取通知或拦截器 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); // 通知或拦截器是 InterceptorAndDynamicMethodMatcher // InterceptorAndDynamicMethodMatcher 用于将方法匹配器与拦截器结合,如果方法匹配器匹配了就是用拦截器进行调用 if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { 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 { // 匹配失败,调用下一个匹配的拦截器 return proceed(); } } // 调用其他拦截器,其他拦截器需要调用,因为传入了this,拦截器链可以使用引用调用本方法,以执行下一个切面或拦截器。 else { return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } } }
“spring中代理的创建方法有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。