千家信息网

spring中代理的创建方法有哪些

发表于:2025-01-28 作者:千家信息网编辑
千家信息网最后更新 2025年01月28日,本篇内容介绍了"spring中代理的创建方法有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!sp
千家信息网最后更新 2025年01月28日spring中代理的创建方法有哪些

本篇内容介绍了"spring中代理的创建方法有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

spring 中创建代理使用了 Jdk 和 Cglib 两种方式创建,JdkDynamicAopProxyObjenesisCglibAopProxy,通过使用配置 AdvisedProxyConfig来管理配置,根据配置决定使用哪种方式创建代理,下面来介绍这几个关键的类。

Advised

Advised 是一个管理 AOP 代理工厂配置的接口,在spring中的所有AopProxy都可以转换为 Advised。

ProxyConfig

在 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个直接子类的相关代码。

  1. ScopedProxyFactoryBean:用于@Scope 注解,实现bean的作用域控制。他实现了 BeanFactoryBeanFactoryAware接口,具有创建、管理bean的能力。

    这个类生成的代理只会记录类的名称,然后根据作用域获取bean,如果是prototype的,则beanFactory会创建一个新的bean。

    public class ScopedProxyFactoryBean extends ProxyConfig      implements FactoryBean, 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());        }}


  2. ProxyProcessorSupport:为 ProxyFactory 提供了常用的公共方法。

  3. 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);                }        }}
    1. AbstractSingletonProxyFactoryBean : 创建单例代理对象,在需要代理的对象实例化后,使用 InitializingBean#afterPropertiesSet()来创建代理,并为其设置前置通知和后置通知。

      public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig                implements FactoryBean, 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);        }}               


    2. AdvisedSupport:实现了 Advised,将 ProxyConfigAdvised进行适配,为 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> methodCache;        // 要实现的代理接口,按顺序存储。        private List> interfaces = new ArrayList<>();        // Advisor 列表        private List 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 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);                }        }}


      ProxyFactoryProxyCreatorSupport 的子类,通过调用父类的方法获取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);        }}


    3. JdkDynamicAopProxy
      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 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是执行切入点、拦截器。

      1. AopProxyUtils#completeProxiedInterfaces()方法获取代理目标的接口,按照规则添加一部分接口SpringProxy、Advised、DecoratingProxy

        // AopProxyUtilsstatic 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;}       


      2. 执行切面和方法拦截器逻辑 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中代理的创建方法有哪些"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

      0