精华内容
下载资源
问答
  • Spring代理的bean中获取代理对象

    千次阅读 2019-09-30 15:50:07
    public class SpringTargetBeanUtils { /** * 获取 目标对象 * * @param proxy 代理对象 * @return * @throws Exception */ public static Object getTarget(Object proxy) throws Exc...
    public class SpringTargetBeanUtils {
        /**
         * 获取 目标对象
         *
         * @param proxy 代理对象
         * @return
         * @throws Exception
         */
        public static Object getTarget(Object proxy) throws Exception {
            if (!AopUtils.isAopProxy(proxy)) {
                return proxy;//不是代理对象
            }
            if (AopUtils.isJdkDynamicProxy(proxy)) {
                return getJdkDynamicProxyTargetObject(proxy);
            } else { //cglib
                return getCglibProxyTargetObject(proxy);
            }
        }
    
    
        private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
            Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
            h.setAccessible(true);
            Object dynamicAdvisedInterceptor = h.get(proxy);
    
            Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
            advised.setAccessible(true);
    
            Object target = ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
    
            return target;
        }
    
    
        private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
            Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
            h.setAccessible(true);
            AopProxy aopProxy = (AopProxy) h.get(proxy);
    
            Field advised = aopProxy.getClass().getDeclaredField("advised");
            advised.setAccessible(true);
    
            Object target = ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget();
    
            return target;
        }

     

    展开全文
  • spring中如果在方法上添加了诸如@Transactional、@Cacheable、@Scheduled、@Async或是切面之类注解,那么这个类就将由spring生成其代理对象,对指定方法进行相关的包装。当该方法在其他对象中被调用时是可以正常...

    问题

    在spring中如果在方法上添加了诸如@Transactional@Cacheable或是切面之类的注解,那么这个类就将由spring生成其代理对象,对指定方法进行相关的包装。当该方法在其他对象中被调用时是可以正常触发代理方法的,然而在本类的方法中进行内部调用时却不会,最终调用的还是原始方法。

    class Service {
        public void methodA(){
            methodB();
        }
        @Transactional
        public void methodB(){
            // do something
        }
    }
    

    也就是说通过methodA调用methodB不会走代理方法,这是为什么呢?

    原因分析

    我们知道spring生成代理对象常见的有两种方式,一种是基于接口的JDK动态代理,一种是基于子类的CGLIB风格代理,可通过proxyTargetClass属性来控制。JDK文档中的一段话:

    Users can control the type of proxy that gets created for FooService using the proxyTargetClass() attribute. The following enables CGLIB-style ‘subclass’ proxies as opposed to the default interface-based JDK proxy approach.

    当为其配置了false时强制使用JDK动态代理,代理对象必须实现接口;当配置为true时强制使用CGLIB风格代理,代理方法不可使用final修饰;当没有配置该项时spring将自动选择有效的代理方式来实现。

    JDK动态代理情况

    JDK动态代理大家应该都比较熟悉了,这儿列出大致实现步骤,进而说明为什么无法触发代理方法。

    public interface Subject
    {
        public void methodA();
        public void methodB();
    }
    
    public class RealSubject implements Subject
    {
        public void methodA()
        {
            // do something
        }
        public void methodB()
        {
            // do something
        }
    }
    
    public class InvocationHandlerImpl implements InvocationHandler
    {
     
        /**
         * real proxied object
         */
        private Object subject;
     
        public InvocationHandlerImpl(Object subject)
        {
            this.subject = subject;
        }
     
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        {
            // do something before invocation
     
            Object returnValue = method.invoke(subject, args);
     
            // do something after invocation
     
            return returnValue;
        }
    }
    
    // generate proxy step
    Subject realSubject = new RealSubject();
    
    InvocationHandler handler = new InvocationHandlerImpl(realSubject);
    
    ClassLoader loader = realSubject.getClass().getClassLoader();
    Class[] interfaces = realSubject.getClass().getInterfaces();
    
    Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);
    
    subject.methodA();
    

    我们可以看到真实对象realSubject其实是放入的handler中,然后传给Proxy来生成代理对象的。我们用反编译工具看下最终生成的代理对象类:

    public final class ProxySubject extends Proxy implements Subject
    {
        private static Method m1;
    	private static Method m2;
    
        public ProxySubject(InvocationHandler paramInvocationHandler)
        {
            super(paramInvocationHandler);
        }
    
        public final void methodA()
        {
            try
            {
                this.h.invoke(this, m1, null);
            }
            catch (Error|RuntimeException localError)
            {
                throw localError;
            }
        }
        
        public final void methodB()
        {
            try
            {
                this.h.invoke(this, m2, null);
            }
            catch (Error|RuntimeException localError)
            {
                throw localError;
            }
        }
        
        static
        {
            m1 = Class.forName("xxx.Subject").getMethod("methodA", new Class[0]);
    		m2 = Class.forName("xxx.Subject").getMethod("methodB", new Class[0]);
        }
    }
    

    为了方便理解上面删除了一些其他不影响的代码。我们可以看到针对代理方法methodA的调用,本质调用的是h.invoke(this, m1, null),也就是handler中的method.invoke(subject, args)语句。这儿的subject为传入的真实对象,因此如果在methodA方法中调用methodB,那就直接调用了内部的真实对象的methodB方法。也就是说代理对象ProxySubject所包装的方法仅适用于外部调用者直接访问,内部调用是无法再走代理过的方法的。

    CGLIB风格代理情况

    注意spring中使用的是CGLIB风格的代理,而不是正宗的CGLIB代理,我们先看下正宗的CGLIB代理实现方式

    public class Service {  
        public void methodA() {  
            methodB();
        }  
        public void methodA() {  
            // do something  
        }  
    }
    
    public class MyMethodInterceptor implements MethodInterceptor {
        public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
            // do something before invocation
            Object object = proxy.invokeSuper(obj, arg);
            // do something after invocation
            return object;
        }
    }
    
    // generate proxy step
    Enhancer enhancer = new Enhancer();  
    enhancer.setSuperclass(Service.class);  
    enhancer.setCallback(new MyMethodInterceptor());  
    Service service = (Service)enhancer.create();
    service.methodA()
    

    CGLib使用字节码增强器Enhancer生成代理类的字节码,对应的反编译内容为:

    public class Service$$EnhancerByCGLIB$$123aabb extends Service implements Factory
    {
        private boolean CGLIB$BOUND;
        private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
        private static final Callback[] CGLIB$STATIC_CALLBACKS;
        private MethodInterceptor CGLIB$CALLBACK_0;
        private static final Method CGLIB$g$0$Method;
        private static final MethodProxy CGLIB$g$0$Proxy;
        private static final Object[] CGLIB$emptyArgs;
        private static final Method CGLIB$f$1$Method;
        private static final MethodProxy CGLIB$f$1$Proxy;
    
        static void CGLIB$STATICHOOK1()
        {
            CGLIB$THREAD_CALLBACKS = new ThreadLocal();
            CGLIB$emptyArgs = new Object[0];
            Class localClass1 = Class.forName("Service$$EnhancerByCGLIB$$123aabb");
            Class localClass2;
            Method[] tmp60_57 = ReflectUtils.findMethods(new String[] { "methodA", "()V", "methodB", "()V" }, (localClass2 = Class.forName("xxx.Service")).getDeclaredMethods());
            CGLIB$g$0$Method = tmp60_57[0];
            CGLIB$g$0$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "methodA", "CGLIB$g$0");
            CGLIB$f$1$Method = tmp60_57[1];
            CGLIB$f$1$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "methodB", "CGLIB$f$1");
        }
    
        final void CGLIB$g$0()
        {
            super.methodA();
        }
    
        public final void methodA()
        {
            MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
            if (tmp4_1 == null)
            {
                CGLIB$BIND_CALLBACKS(this);
                tmp4_1 = this.CGLIB$CALLBACK_0;
            }
            if (this.CGLIB$CALLBACK_0 != null) {
                tmp4_1.intercept(this, CGLIB$g$0$Method, CGLIB$emptyArgs, CGLIB$g$0$Proxy);
            }
            else{
                super.methodA();
            }
        }
        
        final void CGLIB$g$1()
        {
            super.methodB();
        }
    
        public final void methodB()
        {
            MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
            if (tmp4_1 == null)
            {
                CGLIB$BIND_CALLBACKS(this);
                tmp4_1 = this.CGLIB$CALLBACK_0;
            }
            if (this.CGLIB$CALLBACK_0 != null) {
                tmp4_1.intercept(this, CGLIB$g$0$Method, CGLIB$emptyArgs, CGLIB$g$0$Proxy);
            }
            else{
                super.methodB();
            }
        }
    }
    

    我们重点看下代理方法methodA调用的是super.methodA(),而该父类方法执行的是methodB(),由于子类继承重写了methodB方法,所以此时将调用子类(代理类)中的methodB方法。也就是说使用CGLIB方式是支持代理中自我调用的,那为什么spring中不可以呢?原因刚才也提到过,因为spring使用的是CGLIB风格的代理,生成的代理类大致是如下形式:

    class MyService extends Service {
        private final Service delegate;
    
        @Override
        public void methodA() {
            // do some proxy thing
            delegate.methodA();
            // do some proxy thing
        }
    
        @Override
        public void methodB() {
            // do some proxy thing
            delegate.methodB();
            // do some proxy thing
        }
    }
    

    有没有发现这种方式灰常像动态代理的实现!通过使用delegate.methodA()代替super.methodA(),这样最终还是直接调用了真实对象delegatemethodB方法,坑爹啊有木有……至于spring为什么要这么做呢?我在StackOverflow上找到了几个猜测:

    The behavior of the Cglib-proxies has nothing to do with the way of how cglib works but with how cglib is used by Spring. Cglib is capable of either delegating or subclassing a call. Have a look at Spring’s DynamicAdvisedInterceptor which implements this delegation. Using the MethodProxy, it could instead perform a super method call.
    Spring defines delegation rather than subclassing in order to minimize the difference between using Cglib or Java proxies.

    Maybe the reason was that CGLIB proxies should behave similarly to the default Java dynamic proxies so as to make switching between the two for interface types seamless.

    为了能在java动态代理和cglib代理无缝切换,减小两者的差异,因此使用这种实现方式……

    那么如果想要实现同一个对象中的自我调用,可以通过哪些方式呢?

    解决方案

    在spring官方文档中给出的建议是:

    最好进行代码重构,以便不会发生自我调用,虽然需要你做一些额外工作,但这是最佳的侵入性最低的方式。

    也就是说把方法分到不同的类中,当然他们也给出了其他的实现方式。

    exposeProxy暴露代理方式

    接下来介绍的方法我务必要谨慎地指出,它实在令人可怕。你可以使用该方法彻底将你的类中的逻辑绑定到Spring AOP中。

    通过配置exposeProxy属性来获取代理类,进而在业务逻辑代码中获取代理类。开启方式如@EnableAspectJAutoProxy(exposeProxy = true),该属性的介绍为:

    Indicate that the proxy should be exposed by the AOP framework as a ThreadLocal for retrieval via the org.springframework.aop.framework.AopContext class. Off by default, i.e. no guarantees that AopContext access will work.

    也就是说开启后,在线程执行时spring会将当前对象的代理对象放入ThreadLocal中,通过AopContext提供的方法你可以在任何时候都能获取到代理对象。使用方式:

    public class SimpleService implements Service {
    
       public void methodA() {
          // this works, but... gah!
          ((Service) AopContext.currentProxy()).methodB();
       }
       
       public void methodB() {
          // some logic...
       }
    }
    

    exposeProxy开启后如果依然无法获取到currentProxy可以参考这篇文章

    当然文档中还提到了另一种解决方案:

    使用AspectJ则不会有自我调用的问题,因为它并不是一种基于代理的AOP框架。

    AspectJ

    在开启事务@EnableTransactionManagement、缓存@EnableCaching或是异步请求@EnableAsync时,Spring会提供了两种实现模式:proxy 和 AspectJ。

    AspectJ的开启方式如@EnableTransactionManagement(mode = AdviceMode.ASPECTJ) 。AspectJ有两种织入方式:CTW(Compile Time Weaving,编译期织入)LTW(Load Time Weaving,类加载期织入)

    如果使用CTW,则需要编写 aspect 文件,然后使用 ajc 编译器结合 aspect 文件对源代码进行编译,通常很少使用。

    而LTW类加载期织入是通过字节码编辑技术在类加载期将切面织入目标类中。其核心思想是在目标类的class文件被JVM加载前,通过自定义类加载器或者类文件转换器将横切逻辑织入到目标类的class文件中,然后将修改后class文件交给JVM加载。

    使用AspectJ LTW有两个主要步骤:

    1. 通过JVM的-javaagent参数设置LTW的织入器类包,以代理JVM默认的类加载器
    2. LTW织入器需要一个 aop.xml文件,在该文件中指定切面类和需要进行切面织入的目标类

    具体实现方式参考:
    SpringBoot中使用LoadTimeWeaving技术实现AOP功能
    使用AspectJ LTW(Load Time Weaving)

    展开全文
  • 实现将一个接口动态代理,并将该代理对象在spring容器初始化完成前注册到spring容器中。实现可以通过@Autowired等注释或其他方法从spring容器中获取该代理对象
  • spring有非常多的地方都是使用代理的,但是这些什么使用代理,使用哪种代理代理是在什么时候创建的,怎么运行起效的。这些问题都会是下面的源码中实现的。 1、代理是怎么创建的,什么时候创建的,为什么创建 ...

    spring有非常多的地方都是使用代理的,但是这些什么使用代理,使用哪种代理,代理是在什么时候创建的,怎么运行起效的。这些问题都会是下面的源码中实现的。
    1、代理是怎么创建的,什么时候创建的,为什么创建
    spring的代理创建类都是AbstractAutoProxyCreator的子类,这个抽象类同时又是InstantiationAwareBeanPostProcessor的实现类。
    由于它是BeanPostProcessor的实现类,下面的两个方法就非常重要:
    这里写图片描述
    (图1.1.1)
    这部分代码是在getBean -> doCreateBean时在调用bean的自定义初始化方法之前调用的,从源码中看出如果当前的bean有自定义的目标源对象时创建代理,如果生成了代理,将不再调用bean的自定义初始化方法。
    这里写图片描述
    (图1.1.2)
    这部分代码是在getBean -> doCreateBean时在调用bean的自定义初始化方法之后调用的。
    这里写图片描述
    (图1.1.3)
    从上面源码中看出getAdvicesAndAdvisorsForBean 从所有advisors中获取这个方法 有没切面有没有符合当前bean的advisor ,如果有则包装成代理。
    这里写图片描述
    (图1.1.4)
    在创建代理的源码中看出,会创建一个ProxyFactoy(spring默认使用),会把所有的建言者放进这个代理工厂中去,并返回代理对象。
    这里写图片描述
    (图1.1.5)
    这里写图片描述
    (图1.1.6)
    这里写图片描述
    (图1.1.7)
    ProxyFactory 是ProxyCreatorSupport(是AdvisedSupport的子类)的子类
    是默认使用DefaultAopProxyFactory来实现,同时AdvisedSupport传过去,也就是他自己,这样就把所有的建言信息放到了具体代理创建着中。

    2、代理的是怎么区分创建的
    这里写图片描述
    (图2.1.1)
    从以上源码中看出,当被代理的对象是接口使用的是jdk动态代理,否则使用的是cgLib动态代理。

    3、代理的运行机制
    3.1、jdk动态代理的执行机制
    这里写图片描述
    (图3.1.1)
    这里写图片描述
    (图3.1.2)
    JDK 动态代理从当前代理的adivsorsupport中获取出所有切面建言信息,交由reflectiveMehtodInvocation执行。注意this.advised是advisorSupport的对象名(也就是创建代理时候放进去的),不是Advisor。
    如上代码,如果没有建言则直接调用方法,否则把建言委托给ReflectiveMethodInvocation来执行

    3.2、cglib动态代理
    这里写图片描述
    (图3.2.1)
    这里写图片描述
    (图3.2.2)
    从源码可以看出cglib的代理和jdk动态代理执行方式基本一致。都是交由reflectiveMehtodInvocation执行。
    这里写图片描述
    ReflectiveMethodInvocation 是所有执行被代理方法的核心类 所有代理都继承或使用它的process 使用它的是JdkDynamicAopProxy,继承他的是CglibMethodInvocation

    注:此文只说明了代理对象的创建时间及创建原因,及使用哪种代理的区分和简单的运行原理。
    对于spring 代理的详细原理介绍,结构,及cglib的实现原理和机制会单独写一篇文章。

    展开全文
  • jdk 1.8 环境,1.8 之下的环境应该也可以运行 这些代码,然后 需要导入 jre 下面的 rt.jar 包,这个自己去找下
  • 解决Spring代理实现类报错问题

    千次阅读 2014-06-19 13:51:15
    所以在默认情况下,如果一个目标对象如果实现了接口Spring则会选择JDK动态代理策略动态的创建一个接口实现类(动态代理类)来代理目标对象,可以通俗的理解这个动态代理类是目标对象的另外一个版本,所以这两者之间...
     
    
    Spring1.2:
    将事务代理工厂[TransactionProxyFactoryBean] 或 自动代理拦截器[BeanNameAutoProxyCreator]
    的 proxyTargetClass 属性,设置为true,则使用CGLIB代理,此属性默认为false,使用JDK动态代理.
    以下引用 Spring Framework reference 2.0.5:
    Spring2.0:

    Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理。(建议尽量使用JDK的动态代理)

    如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。若该目标对象没有实现任何接口,则创建一个CGLIB代理。

    如果你希望强制使用CGLIB代理,(例如:希望代理目标对象的所有方法,而不只是实现自接口的方法)那也可以。但是需要考虑以下问题:

    无法通知(advise)Final 方法,因为他们不能被覆写。 
    你需要将CGLIB 2二进制发行包放在classpath下面,与之相较JDK本身就提供了动态代理 
    强制使用CGLIB代理需要将 |aop:config| 的 proxy-target-class 属性设为true:

    |aop:config proxy-target-class="true"|
    ...
    |/aop:config|

    当需要使用CGLIB代理和@AspectJ自动代理支持,请按照如下的方式设置 |aop:aspectj-autoproxy| 的 proxy-target-class 属性:

    |aop:aspectj-autoproxy proxy-target-class="true"/|

    而实际使用的过程中才会发现细节问题的差别,The devil is in the detail.JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。
    CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强。
    Spring是依靠什么来判断采用哪种代理策略来生成AOP代理呢?以下代码就是Spring的判断逻辑  

        //org.springframework.aop.framework.DefaultAopProxyFactory   
        
    //参数AdvisedSupport 是Spring AOP配置相关类   
        public AopProxy createAopProxy(AdvisedSupport advisedSupport)   
                
    throws AopConfigException {   
            
    //在此判断使用JDK动态代理还是CGLIB代理   
            if (advisedSupport.isOptimize() || advisedSupport.isProxyTargetClass()   
                    
    || hasNoUserSuppliedProxyInterfaces(advisedSupport)) {   
                
    if (!cglibAvailable) {   
                    
    throw new AopConfigException(   
                            
    "Cannot proxy target class because CGLIB2 is not available. "  
                                    
    + "Add CGLIB to the class path or specify proxy interfaces.");   
                  }   
                
    return CglibProxyFactory.createCglibProxy(advisedSupport);   
              } 
    else {   
                
    return new JdkDynamicAopProxy(advisedSupport);   
              }   
          }  

    advisedSupport.isOptimize()与advisedSupport.isProxyTargetClass()默认返回都是false,所以在默认情况下目标对象有没有实现接口决定着Spring采取的策略,当然可以设置advisedSupport.isOptimize()或者advisedSupport.isProxyTargetClass()返回为true,这样无论目标对象有没有实现接口Spring都会选择使用CGLIB代理。

    所以在默认情况下,如果一个目标对象如果实现了接口Spring则会选择JDK动态代理策略动态的创建一个接口实现类(动态代理类)来代理目标对象,可以通俗的理解这个动态代理类是目标对象的另外一个版本,所以这两者之间在强制转换的时候会抛出java.lang.ClassCastException。而所以在默认情况下,如果目标对象没有实现任何接口,Spring会选择CGLIB代理, 其生成的动态代理对象是目标类的子类。

    上说的是默认情况下,也可以手动配置一些选项使Spring采用CGLIB代理。 
    org.springframework.transaction.interceptor.TransactionProxyFactoryBean是org.springframework.aop.framework. ProxyConfig的子类,所以可以参照ProxyConfig里的一些设置如下所示,将optimize和proxyTargetClass任意一个设置为true都可以强制Spring采用CGLIB代理。

    如果当需要使用CGLIB代理和@AspectJ自动代理支持,请按照如下的方式设置 |aop:aspectj-autoproxy| 的 proxy-target-class 属性: 
    |aop:aspectj-autoproxy proxy-target-class="true"/|

    这样使用CGLIB代理也就不会出现前面提到的ClassCastException问题了,也可以在性能上有所提高,关键是对于代理对象是否继承接口可以统一使用。

    展开全文
  • spring中获取代理对象代理的目标对象工具类
  • Spring动态代理机制理解

    万次阅读 2018-03-17 16:22:30
    另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制,...
  • Spring IOC---AOP代理对象生成的时机

    千次阅读 多人点赞 2020-12-15 20:52:37
    前置知识3.Spring AOP代理对象生成的时机3.1非提前生成代理对象3.2 提前生成代理对象4. 为什么需要两种动态代理的时机 1.概述 Spring AOP可以采用注解或者xml配置的方式实现,那么在spring的生命周期当中,是在什么...
  • Spring之IOC与动态代理

    千次阅读 2018-12-27 10:27:43
    Spring框架是J2EE开发中一个使用广泛的框架,它使得dao和service层的维护更加便利。Spring框架有两个重要的特征,一个是IOC,另一个是AOP。我们在这里主要介绍IOC,以及IOC中涉及的主要技术。  IOC(Inversion Of ...
  • DelegatingFilterProxy就是一个对于servlet filter的代理,用这个类的好处主要是通过Spring容器来管理servlet filter的生命周期, 还有就是如果filter中需要一些Spring容器的实例,可以通过spring直接注入, 另外...
  • Spring的两种代理方式:JDK动态代理和CGLIB动态代理

    万次阅读 多人点赞 2017-02-10 14:04:59
    代理模式代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象...
  • Spring代理模式:静态代理

    万次阅读 2021-05-25 20:36:33
    为什么要学代理模式? 因为这就是SpringAOP的底层!【面试时,SpringAOP 和 SpringMVC一定会问】 代理模式的分类: 静态代理 动态代理 静态代理 角色分析: 抽象角色:一般会使用接口或抽象类来解决 真是角色...
  • 创建动态代理对象bean,并动态注入到spring容器中

    万次阅读 多人点赞 2019-04-30 00:48:19
    这里mybatis就用到了JDK动态代理,并且将生成的接口代理对象动态注入到Spring容器中。 这里涉及到几个问题。也许有同学会有疑问,我们直接编写好类,加入@Component等注解不是可以注入了吗?或者在配置类(@...
  • 浅谈Spring中JDK动态代理与CGLIB动态代理

    千次阅读 多人点赞 2018-07-04 18:25:00
    代理模式:代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法、实际执行的是被代理类的方法。 JDK代理和CGLIB代理差异 实现差异: - cglib的proxy...
  • Spring框架----基于接口的动态代理

    千次阅读 2020-08-13 09:13:56
    由我们前面对代理的分析 https://blog.csdn.net/qq_39736597/article/details/107971509 有生产商,销售人员和消费者这3个角色,销售人员是中间代理商。代理销售和售后的工作。 而在刚开始的时候,我们并没有销售...
  • Spring Cloud Zuul 统一访问代理

    千次阅读 2019-02-24 17:16:30
    在微服务框中(Spring Cloud)存在很多服务,客户端逐个调用这些服务非常繁琐,Zuul提供了统一访问接口访问这些微服务。zuul的核心是一系列的filters, 其作用可以类比Servlet框架的Filter,或者AOP。 zuul的过滤器之间...
  • Spring AOP代理Controller层

    千次阅读 2016-10-20 23:32:38
    看到spring Aop这块想优化下以前项目的代码,网上看了半天,各种案例,试了又试,没什么效果,说扫描包第一次扫描后,第二次就不会扫描了,所以Aop不会起效..(熟悉Jvm会懂的..) 网上寻它千百度,重要在google搜素时看到个...
  • Spring AOP的底层实现-代理模式

    千次阅读 2018-07-23 01:01:26
    在学习Spring的过程中,留下一下痕迹。 1.Srping的IoC(控制反转) 控制反转,初看这个名词实在显得晦涩难懂。但是它只是说了一个事情,就是我们不再需要自己new对象了,而是交给了Spring提供我们需要的...
  • Spring中的代理 JDK动态代理: 其代理对象必须是某个接口的实现,它是通过运行期间创建一个接口的实现类来完成对目标对象的代理. CGLIB代理: 实现原理类似于JDK的动态代理,只是它在运行期间生成目标类扩展的子类...
  • java动态代理spring动态代理对比

    千次阅读 2016-04-18 21:37:19
    以上是未使用springaop的动态代理,下面将介绍spring实现动态代理的方法: 第一种通知再切面类中配置,注意都是有接口的,这里不再写接口代码: 实现类: package com.leige.aspect; ...
  • Spring中的aop(生成代理对象)

    千次阅读 2019-04-27 14:04:50
    1、Spring中的aop的介绍 ...Spring中是使用动态代理和cglib代理混合使用,优先使用动态代理,如果不能使用动态代理,则使用cglib代理。 2、cglib代理和动态代理 动态代理:被代理对象必须要实现接口,才能产生代理...
  • 切面编程是Spring中非常重要的一个模块,切面编程的实现原理是动态代理,那么动态代理又有两种实现方式:一种方法是直接实现JDK中的InvocationHandler接口,另一种方法是继承CGLIB。 首先如果不是很清楚两者的区别...
  • 应用启动过程中Spring AOP自动配置机制AopAutoConfiguration执行 仅在类 EnableAspectJAutoProxy 存在于classpath并且 spring.aop 没有明确设置为 false 时应用 可以认为等价于主动使用注解 @...
  • 我们都指定spring的动态代理有两种方式,分别是jdk代理和cglib代理spring动态代理的策略是: 1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2、如果目标对象实现了接口,可以强制使用...
  • Spring中的两种代理方式比较

    千次阅读 2018-03-01 10:40:59
    spring框架中,你直接输出一个由spring框架代理创建的对象,和我们自己new一个对象输出的对象的堆栈地址的形式是不同的.这种代理也是spring框架核心AOP的实现基础. 在spring框架中使用了两种代理方式: 1.JDK自带的...
  • Spring动态代理用JDK还是用CGLIB?

    千次阅读 2017-10-04 17:27:59
    切面编程是Spring中非常重要的一个模块,切面编程的实现原理是动态代理,那么动态代理又有两种实现方式,一种方法是直接实现JDK中的InvocationHandler接口,另一种方法是继承CGLIB。那么问题来了,这两种方法有啥...
  • 我们大家都知道,mybatis的mapper接口,我们并没有手动编写实现代码,但仍然能在程序中注入到Spring容器并使用。这里面就用到了动态代理的原理。 下面,我也编写一个接口,代码未给出实现,通过动态代理进行接口的...
  • 之前两篇文章中我们说到了JDK proxy和CGLIB实现动态代理的方式,这回说说Spring的方式。Spring代理对象可通过xml配置方式获得,也可通过ProxyFactory手动编程方式创建对象。我们主要讲手动编程的方式。Spring中的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 271,971
精华内容 108,788
关键字:

spring代理

spring 订阅
友情链接: UtilsImage.zip