美文网首页学好spring,走遍天下都是win
Spring 动态代理不生效问题

Spring 动态代理不生效问题

作者: 藤原咸鱼 | 来源:发表于2020-12-03 10:28 被阅读0次

    1.静态代理,动态代理

    静态代理:代理类和代理目标存在硬编码关系,耦合度高
    动态代理:代理类通过java反射,在jvm运行时动态生成,实现代码解耦

    2.JDK动态代理,cglib动态代理

    JDK动态代理:通过反射类Proxy以及InvocationHandler回调接口实现的,被代理类必须实现自接口
    cglib动态代理:通过ASM(字节码技术)框架生成代理类,被代理对象为public且不为final修饰,因为cglib原理是动态生成被代理类的子类

    接口(Subject):
    interface HelloService {
        void sayHello();
    }
    
    委托类:
    class HelloServiceImpl implements HelloService {
        @Override
        public void sayHello() {
            System.out.println("Hello World!");
        }
    }
    
    JDK代理核心代码,构造代理对象
    class HelloServiceDynamicProxy {
    
        private HelloService helloService;
        public HelloServiceDynamicProxy(HelloService helloService) {
            this.helloService = helloService;
        }
    
        public Object getProxyInstance() {
            return Proxy.newProxyInstance(helloService.getClass().getClassLoader(), helloService.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("Before say hello...");
                    Object ret = method.invoke(helloService, args);
                    System.out.println("After say hello...");
                    return ret;
                }
            });
        }
    }
     }
    
    测试类:
    public class HelloServieDynamicProxyTest {
        public static void main(String[] args){
            HelloService helloService = new HelloServiceImpl();
            HelloService dynamicProxy = (HelloService) new HelloServiceDynamicProxy(helloService).getProxyInstance();
            dynamicProxy.sayHello();
        }
    }
    
    输出结果:
    Before say hello...
    Hello World!
    After say hello...
    

    了解过动态代理实现后,我们知道不管何种代理,作用对象是类,通过生成代理类,调用其方法。

    结论:
    Spring AOP 则是基于动态代理底层实现,对目标类的方法调用植入增强功能代码

    所以基于aop的注解(例:@Transactional)具有共性特征自调用失效

    (调用类中第一个方法没有注解,那么该方法这种调用本类中的其他注解方法都不起作用)

    粗暴的解决方法
    // 在A方法内部调用B方法
    // 1.直接调用B,注解失效。
    // 2.拿到代理类对象,再调用B(X类的B方法)。
    ((X)AopContext.currentProxy()).B()

    相关文章

      网友评论

        本文标题:Spring 动态代理不生效问题

        本文链接:https://www.haomeiwen.com/subject/gixmwktx.html