专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java 动态代理详解:从入门到实战(java动态代理有几种方式)

temp10 2024-10-04 12:32:37 java教程 10 ℃ 0 评论

在Java编程中,代理模式是一种非常重要的设计模式。代理模式可以分为静态代理和动态代理。今天我们主要来聊聊动态代理。动态代理在很多框架中都有广泛的应用,比如Spring AOP、MyBatis等。本文将详细介绍Java动态代理的原理、使用场景,并通过代码示例帮助大家更好地理解。

什么是动态代理?

动态代理是指在程序运行时创建代理类,而不是在编译时确定代理类。动态代理可以在不修改目标对象的情况下,为目标对象添加额外的功能。

Java 动态代理详解:从入门到实战(java动态代理有几种方式)

动态代理的实现方式

Java中主要有两种方式实现动态代理:

1. JDK动态代理

2. CGLIB动态代理

JDK动态代理

JDK动态代理是基于接口的代理。它要求目标对象必须实现一个或多个接口。

实现步骤

1. 定义接口和实现类

2. 创建InvocationHandler接口的实现类

3. 使用Proxy类生成代理对象

代码示例

package com.dhzx.code.jdkDynamicProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 1、定义接口
 */
interface HelloService {
    void sayHello();
}

/**
 * 2、实现接口
 */
class HelloServiceImpl implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("Hello World!");
    }
}

/**
 * 3、创建 InvocationHandler实现类
 */
class HelloServiceInvocationHandler implements InvocationHandler {

    private Object targert;

    public HelloServiceInvocationHandler(Object targert) {
        this.targert = targert;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法调用前");
        Object obj = method.invoke(targert, args);
        System.out.println("方法调用后");
        return obj;
    }
}

/**
 * JDK 动态代理示例
 */
class JDKDynamicProxyDemo {
    public static void main(String[] args) {
        // 4、创建目标方法
        HelloService helloService = new HelloServiceImpl();
        // 5、创建代理对象
        HelloService proxy = (HelloService) Proxy.newProxyInstance(helloService.getClass().getClassLoader(), helloService.getClass().getInterfaces(), new HelloServiceInvocationHandler(helloService));
        // 6、调用代理对象的方法
        proxy.sayHello();
    }
}
输出结果:
方法调用前
Hello World!
方法调用后

在上面的示例中,我们定义了一个HelloService接口及其实现类HelloServiceImpl。然后,我们创建了一个HelloServiceInvocationHandler类,实现了InvocationHandler接口。在invoke方法中,我们可以在方法调用前后添加自定义逻辑。最后,我们使用Proxy.newProxyInstance方法创建了代理对象,并调用了代理对象的方法。

CGLIB动态代理

CGLIB动态代理是基于继承的代理,它不需要目标对象实现接口。CGLIB通过生成目标类的子类来实现代理。

实现步骤

1. 引入CGLIB库

2. 创建MethodInterceptor接口的实现类

3. 使用Enhancer类生成代理对象

代码示例

<!-- 引入CGLIB库 -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>
package com.dhzx.code.cglibDynamicProxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 1、创建目标类
 */
class HelloService {

    void sayHello() {
        System.out.println("Hello World!");
    }
}

/**
 * 2、创建 MethodInterceptor 实现类
 */
class HelloServiceInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("方法调用前");
        Object obj = methodProxy.invokeSuper(o, objects);
        System.out.println("方法调用后");
        return obj;
    }
}

class CGLIBDynamicProxyDemo {
    public static void main(String[] args) {
        // 3、创建Enhancer对象(字节码增强器)
        Enhancer enhancer = new Enhancer();
        // 4、告诉cglib要继承哪个类
        enhancer.setSuperclass(HelloService.class);
        // 5、设置回调接口
        enhancer.setCallback(new HelloServiceInterceptor());

        // 6、创建代理对象(生成源码,编译class,加载到JVM)
        HelloService helloService = (HelloService) enhancer.create();
        helloService.sayHello();
    }
}
输出结果:
方法调用前
Hello World!
方法调用后

在上面的示例中,我们创建了一个目标类HelloService,然后创建了一个HelloServiceInterceptor类,实现了MethodInterceptor接口。在intercept方法中,我们可以在方法调用前后添加自定义逻辑。最后,我们使用Enhancer类生成了代理对象,并调用了代理对象的方法。

动态代理的应用场景

动态代理在实际开发中有很多应用场景,比如:

1. AOP(面向切面编程):动态代理是AOP的核心技术之一。通过动态代理,可以在不修改目标对象的情况下,为目标对象添加额外的功能,比如日志记录、权限校验、事务管理等。

2. 远程方法调用(RMI):动态代理可以用于实现远程方法调用,使得客户端可以像调用本地方法一样调用远程方法。

3. Mock测试:在单元测试中,动态代理可以用于创建Mock对象,模拟依赖对象的行为。

总结

Java动态代理是一种非常强大的技术,可以在不修改目标对象的情况下,为目标对象添加额外的功能。本文详细介绍了JDK动态代理和CGLIB动态代理的实现方式,并通过代码示例帮助大家更好地理解动态代理的原理和应用场景。希望这篇文章能对你有所帮助!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表