请使用JDK编写一个动态代理的实际应用案例代码。

参考回答

问题:使用JDK编写一个动态代理的实际应用案例代码。

下面我们将编写一个实际应用案例,使用JDK动态代理来实现一个日志功能。每当调用目标方法时,代理会在方法执行前后分别打印日志。我们会通过JDK的动态代理机制来完成这一功能。

详细讲解与拓展

1. 定义接口

首先,我们定义一个业务接口Service,它包含一个performAction方法,用于模拟实际业务操作。

public interface Service {
    void performAction(String action);
}
Java

2. 实现目标类

然后,我们定义一个目标类ServiceImpl,它实现了Service接口,并提供具体的业务逻辑。

public class ServiceImpl implements Service {
    @Override
    public void performAction(String action) {
        System.out.println("Executing action: " + action);
    }
}
Java

3. 创建InvocationHandler

接下来,我们实现InvocationHandler接口,重写invoke()方法来实现代理逻辑。在invoke()方法中,我们添加日志功能,记录方法执行前后的日志。

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

public class ServiceInvocationHandler implements InvocationHandler {
    private final Object target;

    public ServiceInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 记录方法执行前的日志
        System.out.println("Logging: Before invoking method " + method.getName());

        // 执行目标方法
        Object result = method.invoke(target, args);

        // 记录方法执行后的日志
        System.out.println("Logging: After invoking method " + method.getName());

        return result;
    }
}
Java

4. 创建代理对象

使用Proxy.newProxyInstance()方法来创建代理对象。我们将ServiceImpl作为目标对象,通过InvocationHandler来为其添加日志功能。

import java.lang.reflect.Proxy;

public class ProxyTest {
    public static void main(String[] args) {
        // 创建目标对象
        Service service = new ServiceImpl();

        // 创建 InvocationHandler
        ServiceInvocationHandler handler = new ServiceInvocationHandler(service);

        // 创建代理对象
        Service proxy = (Service) Proxy.newProxyInstance(
                service.getClass().getClassLoader(), // 类加载器
                new Class[]{Service.class}, // 目标对象实现的接口
                handler // InvocationHandler
        );

        // 调用代理对象的方法
        proxy.performAction("Sample Action");
    }
}
Java

5. 输出结果

Logging: Before invoking method performAction
Executing action: Sample Action
Logging: After invoking method performAction

代码解析

  1. 接口定义Service接口声明了performAction方法,表示我们的目标业务操作。
  2. 目标类实现ServiceImpl类实现了Service接口,并提供了具体的业务逻辑。
  3. InvocationHandlerServiceInvocationHandler类实现了InvocationHandler接口。在invoke()方法中,我们添加了日志功能,记录方法执行前后的日志,然后通过method.invoke(target, args)调用目标对象的方法。
  4. 代理对象创建:在ProxyTest类中,我们使用Proxy.newProxyInstance()创建代理对象。newProxyInstance方法的参数包括目标类的类加载器、目标类实现的接口以及我们的InvocationHandler实例。

总结

通过以上代码,我们使用了JDK动态代理来实现日志功能。每当调用proxy.performAction("Sample Action")时,代理对象会拦截该方法调用,并在方法执行前后输出日志。JDK动态代理非常适合用来为接口方法添加统一的横切逻辑,例如日志记录、权限校验、性能监控等。

发表评论

后才能评论