spring默认代理是什么

不及物动词 其他 37

回复

共3条回复 我来回复
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    spring默认的代理是基于接口的JDK动态代理。在使用接口来定义Bean的时候,Spring会默认使用JDK动态代理来创建代理对象。这种动态代理是通过实现目标接口来生成代理对象,并在代理对象的方法中调用目标对象的方法。

    JDK动态代理的原理是利用反射机制,在运行时动态创建代理类并生成代理对象。当方法被调用时,代理对象会通过反射调用目标对象的方法,并进行额外的操作,如事务管理、日志记录等。这种基于接口的代理可以在运行时轻松地切换代理对象,而无需修改目标对象的代码。

    要使用JDK动态代理,目标类必须实现一个或多个接口。Spring通过检查目标类的接口来判断是否使用JDK动态代理。如果目标类实现了接口,则使用JDK动态代理;如果目标类没有实现接口,则Spring将使用CGLIB(Code Generation Library)来创建代理对象。

    总结一下,Spring默认使用基于接口的JDK动态代理来创建代理对象。这种代理方式具有灵活性和可扩展性,可以方便地在运行时进行代理对象的切换和配置。

    1年前 0条评论
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    Spring 默认使用的代理是 JDK 动态代理。

    Spring 的 AOP 功能实现方式有两种:JDK 动态代理和 CGLIB 代理。其中,如果被代理的目标类实现了至少一个接口,则 Spring 使用 JDK 动态代理;如果被代理的目标类没有实现任何接口,则 Spring 使用 CGLIB 代理。

    JDK 动态代理是在运行时动态生成一个实现代理接口的匿名类,而 CGLIB 代理是在运行时通过字节码增强技术,动态生成一个被代理目标类的子类。两者在使用方式和原理上有所区别。

    Spring 默认使用 JDK 动态代理的原因有以下几点:

    1. 接口的广泛使用:Spring 认为在设计良好的应用程序中,接口在组织和管理代码上有很多好处,故默认使用 JDK 动态代理。JDK 动态代理只能代理实现了接口的类,而 CGLIB 代理则可以代理没有接口的类。

    2. 遵循面向接口编程原则:Spring 倡导面向接口编程的思想,在依赖注入和控制反转等场景中,接口是实现依赖注入和控制反转的重要组件,使用 JDK 动态代理能很好地支持面向接口编程。

    3. 避免生成大量的代理类:JDK 动态代理是基于接口生成代理类的,相对而言,生成的代理类数量较少。而 CGLIB 代理是基于继承来实现的,每个被代理的类都会生成一个专门用于代理的子类,这样会导致生成大量的代理类。

    4. 性能考虑:JDK 动态代理相对于 CGLIB 代理在性能上有优势。因为 JDK 动态代理是基于接口来实现的,利用了 Java 原生的反射技术,而 CGLIB 代理则是通过生成子类来实现代理,需要通过增加方法调用的过程来进行调用,性能相对较低。

    5. 兼容性:JDK 动态代理是 Java 标准库中的一部分,具有很好的兼容性。而 CGLIB 代理则是第三方库,使用时可能需要额外的依赖,并且可能在一些限制特殊环境中无法使用。因此,为了保证更广泛的兼容性,Spring 默认选择使用 JDK 动态代理。

    1年前 0条评论
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    在Spring框架中,默认使用的是JDK动态代理作为代理机制。JDK动态代理是一种基于接口的代理实现方式,它通过创建一个实现接口的代理类来实现代理功能。在运行时,根据目标对象实现的接口信息,动态生成一个代理类,并在代理类中调用目标对象的方法。JDK动态代理只能代理实现了接口的类,不能代理没有实现接口的类。

    下面我们来详细讲解Spring框架中JDK动态代理的使用方法和操作流程。

    JDK动态代理的使用方法和操作流程

    1. 首先,定义一个接口(或者使用已有的接口),作为目标对象实现的接口。这个接口定义了目标对象中的方法。
    public interface Foo {
        void doSomething();
    }
    
    1. 创建目标对象,实现上述接口。
    public class FooImpl implements Foo {
        @Override
        public void doSomething() {
            System.out.println("Do something...");
        }
    }
    
    1. 创建一个InvocationHandler接口的实现类,实现invoke方法,用于处理代理对象的方法调用。
    public class MyInvocationHandler implements InvocationHandler {
        private Object target; // 目标对象
        
        public MyInvocationHandler(Object target) {
            this.target = target;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 在目标对象的方法执行前进行一些操作
            System.out.println("Before method invocation...");
            
            // 调用目标对象的方法
            Object result = method.invoke(target, args);
            
            // 在目标对象的方法执行后进行一些操作
            System.out.println("After method invocation...");
            
            return result;
        }
    }
    
    1. 使用Proxy类的newProxyInstance方法创建代理对象。
    Foo foo = new FooImpl(); // 创建目标对象
    InvocationHandler handler = new MyInvocationHandler(foo); // 创建InvocationHandler接口的实现类
    Foo proxyFoo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[]{Foo.class}, handler); // 创建代理对象
    
    1. 最后,通过代理对象调用目标对象的方法。
    proxyFoo.doSomething(); // 调用目标对象的方法
    

    在上述代码中,代理对象proxyFoo就是动态生成的代理类对象。当调用代理对象的doSomething方法时,会先执行InvocationHandler接口实现类中的invoke方法。在invoke方法中,可以在调用目标对象方法前后进行一些操作,比如记录日志、处理事务等。

    JDK动态代理的优点是可以在运行时动态生成代理类,并在代理类中调用目标对象的方法,无需修改目标对象的代码。但缺点是只能代理实现了接口的类,不能代理没有实现接口的类。

    1年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部