spring 代理的创建

复制粘贴侠
• 阅读 1450

[toc]

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<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());
        }
    }
  1. 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);
        }
    }
}
  1. 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);
        }
    }        
  1. 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<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);
        }
    }
}

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);
    }
}
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<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是执行切入点、拦截器。

  1. 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;
}    
  1. 执行切面和方法拦截器逻辑 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);
            }
        }
    }
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Easter79 Easter79
3年前
spring框架中JDK和CGLIB动态代理区别
!(https://oscimg.oschina.net/oscnet/5f05209beb8dc8b9363b074facbc7a4dd50.png)转载:https://blog.csdn.net/yhl\_jxy/article/details/80635012前言JDK动态代理实现原理(jdk8):https://blog.csdn
Wesley13 Wesley13
3年前
CGLIB介绍与原理(通过继承的动态代理)
一、什么是CGLIB?CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。二、CGLIB原理CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的
Easter79 Easter79
3年前
Spring的两种代理JDK和CGLIB的区别浅谈
一、原理区别:java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以
Easter79 Easter79
3年前
Spring的Aop调用当前类的两种方法
我们知道Spring对于AOP实现有两种方法,如果类是接口实现类,则采用JDK动态代理实现AOP。如果类没有实现接口,则采用cglib生成子类做增强,以实现代理类的目的,其实运行时找到的是这个代理类,而不是原类。所以在一个代理类中调用内部的方法,是不是再走AOP逻辑的,那有什么好的方法可以解决这种问题吗?基于上面的思路有两种解决办法方法一:直接从
Wesley13 Wesley13
3年前
Java 通过getbean取出的类为什么要强转为接口类
这个问题是之前一个同学问我的,这些是我在网上找到的资料,由于我自己也没有完全搞明白,先大概记录一下首先问题是为什么在bean文件中注入的是实现类,但是通过getBean()取出的时候却必须强制转化为接口类。这个问题应该是和spring中配置的代理模式相关的,即到底是使用JDK动态代理还是Cglib代理。关于代理模式这个问题spring的文档中这么
Wesley13 Wesley13
3年前
AOP的自动代理
Spring的aop机制提供两类方式实现类代理。一种是单个代理,一种是自动代理。单个代理通过ProxyFactoryBean来实现(就如上面的配置)。自动代理:自动代理能够让切面定义来决定那个bean需要代理,不需要我们为特定的bean明确的创建代理从而提供一个更完整的aop实现通过BeanNameAutoProxyCreator或者Defaul
Easter79 Easter79
3年前
Spring事务——使用TransactionProxyFactoryBean创建事务代理
    Spring同时支持编程式事务策略和声明式事务策略,大部分时候,我们都推荐采用声明式事务策略。使用声明式事务策略的优势十分明显:声明式事务能大大降低开发者的代码书写量,而且声明式事务几乎不影响应用的代码。因此,不论底层事务策略如何变化,应用程序都无需任何改变应用程序代码无需任何事务处理代码,可以更专注于业务逻辑的实