MST

星途 面试题库

面试题:Java动态代理如何在运行时为接口生成代理类

假设有一个简单的业务接口 `UserService` 包含 `login` 和 `register` 方法,要求使用Java动态代理为 `UserService` 接口生成代理类,在代理类中对每个方法调用前后打印日志,描述实现思路并给出关键代码。
50.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 实现思路
    • 创建 InvocationHandler 接口的实现类,在 invoke 方法中实现日志打印逻辑以及目标方法的调用。
    • 使用 Proxy 类的 newProxyInstance 方法生成代理对象,该方法需要传入类加载器、目标接口数组以及 InvocationHandler 实例。
  2. 关键代码
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 用户服务接口
interface UserService {
    void login(String username, String password);
    void register(String username, String password);
}

// 用户服务接口实现类
class UserServiceImpl implements UserService {
    @Override
    public void login(String username, String password) {
        System.out.println("实际登录逻辑,用户名:" + username + ",密码:" + password);
    }

    @Override
    public void register(String username, String password) {
        System.out.println("实际注册逻辑,用户名:" + username + ",密码:" + password);
    }
}

// 自定义InvocationHandler
class UserServiceInvocationHandler implements InvocationHandler {
    private Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法 " + method.getName() + " 调用前,参数:" + java.util.Arrays.toString(args));
        Object result = method.invoke(target, args);
        System.out.println("方法 " + method.getName() + " 调用后");
        return result;
    }
}

// 动态代理生成代理类
class ProxyFactory {
    public static Object getProxy(Object target) {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new UserServiceInvocationHandler(target)
        );
    }
}

使用示例:

public class Main {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        UserService proxy = (UserService) ProxyFactory.getProxy(userService);
        proxy.login("testUser", "testPassword");
        proxy.register("newUser", "newPassword");
    }
}