JDK 动态代理

简介: JDK 动态代理

Java 中的动态代理是一种非常强大且灵活的机制,用于在运行时创建代理类并处理方法调用。动态代理主要有两种方式:JDK 动态代理和 CGLIB 动态代理。下面将详细介绍这两种动态代理的实现和使用场景。

JDK 动态代理

JDK 动态代理是基于接口的代理,这意味着它只能代理实现了接口的类。它主要依赖于 java.lang.reflect 包下的 InvocationHandler 接口和 Proxy 类。

基本步骤

  1. 定义接口和实现类

    public interface Hello {
         
        void sayHello();
    }
    
    public class HelloImpl implements Hello {
         
        @Override
        public void sayHello() {
         
            System.out.println("Hello, World!");
        }
    }
    
  2. 实现 InvocationHandler 接口

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class HelloInvocationHandler implements InvocationHandler {
         
        private Object target;
    
        public HelloInvocationHandler(Object target) {
         
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         
            System.out.println("Before method call");
            Object result = method.invoke(target, args);
            System.out.println("After method call");
            return result;
        }
    }
    
  3. 创建代理对象

    import java.lang.reflect.Proxy;
    
    public class Main {
         
        public static void main(String[] args) {
         
            Hello hello = new HelloImpl();
            HelloInvocationHandler handler = new HelloInvocationHandler(hello);
    
            Hello proxy = (Hello) Proxy.newProxyInstance(
                    hello.getClass().getClassLoader(),
                    hello.getClass().getInterfaces(),
                    handler);
    
            proxy.sayHello();
        }
    }
    

    在以上代码中,Proxy.newProxyInstance 方法用于创建代理对象,它需要三个参数:类加载器、被代理类实现的接口们、InvocationHandler 实例。

CGLIB 动态代理

CGLIB(Code Generation Library)是一种强大的字节码生成库,它可以在运行时生成代理类,并且不需要实现接口。这使得它可以代理那些没有实现接口的类。

基本步骤

  1. 添加 CGLIB 依赖
    如果使用 Maven,可以在 pom.xml 中添加以下依赖:

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.3.0</version>
    </dependency>
    
  2. 定义目标类

    public class HelloService {
         
        public void sayHello() {
         
            System.out.println("Hello, World!");
        }
    }
    
  3. 实现 MethodInterceptor 接口

    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class HelloMethodInterceptor implements MethodInterceptor {
         
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
         
            System.out.println("Before method call");
            Object result = proxy.invokeSuper(obj, args);
            System.out.println("After method call");
            return result;
        }
    }
    
  4. 创建代理对象

    import net.sf.cglib.proxy.Enhancer;
    
    public class Main {
         
        public static void main(String[] args) {
         
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(HelloService.class);
            enhancer.setCallback(new HelloMethodInterceptor());
    
            HelloService proxy = (HelloService) enhancer.create();
            proxy.sayHello();
        }
    }
    

    在以上代码中,Enhancer 类用于创建代理类实例。setSuperclass 方法指定要代理的目标类,setCallback 方法设置方法拦截器。

选择哪种动态代理?

  • JDK 动态代理:适用于目标对象已经实现一个或多个接口的情况。
  • CGLIB 动态代理:适用于目标对象没有实现接口或者需要代理类的子类的情况。

动态代理的应用场景

动态代理在很多实际应用中非常有用,特别是在以下场景:

  • AOP(面向切面编程):如 Spring AOP,通过动态代理实现横切关注点(如日志记录、事务管理等)。
  • 远程方法调用(RPC):通过代理屏蔽底层通信细节,使得调用远程服务像调用本地方法一样简单。
  • 权限控制:通过代理在方法调用前后进行权限检查。
  • 缓存:在方法调用前检查缓存,如果存在则返回缓存结果,否则调用方法并将结果存入缓存。

总之,Java 的动态代理是一种强大且灵活的技术,能够有效解耦业务逻辑和横切关注点,提高代码的可维护性和可扩展性。

目录
相关文章
|
11月前
|
缓存 Java 数据库连接
分析JDK动态代理的实现
分析JDK动态代理的实现
67 0
|
3月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
21天前
|
设计模式 Java API
[Java]静态代理与动态代理(基于JDK1.8)
本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
17 0
[Java]静态代理与动态代理(基于JDK1.8)
|
1月前
|
Java
【编程进阶知识】静态代理、JDK动态代理及Cglib动态代理各自存在的缺点及代码示例
本文介绍了三种Java代理模式:静态代理、JDK动态代理和Cglib动态代理。静态代理针对特定接口或对象,需手动编码实现;JDK动态代理通过反射机制实现,适用于所有接口;Cglib动态代理则基于字节码技术,无需接口支持,但需引入外部库。每种方法各有优缺点,选择时应根据具体需求考虑。
18 1
|
3月前
|
Java API 开发者
Jdk动态代理为啥不能代理Class?
该文章主要介绍了JDK动态代理的原理以及为何JDK动态代理不能代理Class。
Jdk动态代理为啥不能代理Class?
|
3月前
|
开发者 C# 容器
【独家揭秘】当WPF邂逅DirectX:看这两个技术如何联手打造令人惊艳的高性能图形渲染体验,从环境搭建到代码实践,一步步教你成为图形编程高手
【8月更文挑战第31天】本文通过代码示例详细介绍了如何在WPF应用中集成DirectX以实现高性能图形渲染。首先创建WPF项目并使用SharpDX作为桥梁,然后在XAML中定义承载DirectX内容的容器。接着,通过C#代码初始化DirectX环境,设置渲染逻辑,并在WPF窗口中绘制图形。此方法适用于从简单2D到复杂3D场景的各种图形处理需求,为WPF开发者提供了高性能图形渲染的技术支持和实践指导。
212 0
|
3月前
|
设计模式 Java C++
揭秘!JDK动态代理VS CGLIB:一场关于Java代理界的‘宫心计’,你站哪队?
【8月更文挑战第24天】Java 动态代理是一种设计模式,允许在不改动原类的基础上通过代理类扩展功能。主要实现方式包括 JDK 动态代理和 CGLIB。前者基于接口,利用反射机制在运行时创建代理类;后者采用继承方式并通过字节码技术生成子类实现类的代理。两者在实现机制、性能及适用场景上有明显差异。JDK 动态代理适用于有接口的场景,而 CGLIB 更适合代理未实现接口的类,尽管性能更优但存在一些限制。开发者可根据需求选择合适的代理方式。
172 0
|
5月前
|
设计模式 Java 程序员
java动态代理(JDK和cglib)
java动态代理(JDK和cglib)
30 0
|
5月前
|
设计模式 Java 程序员
java动态代理(JDK和cglib)
java动态代理(JDK和cglib)
40 0
|
5月前
|
Java Spring
深入解析Spring源码,揭示JDK动态代理的工作原理。
深入解析Spring源码,揭示JDK动态代理的工作原理。
59 0