Java反射机制剖析(三)-简单谈谈动态代理
发布日期:2025-04-02 02:28:21 浏览次数:12 分类:精选文章

本文共 3839 字,大约阅读时间需要 12 分钟。

替换技术内容

通过学习反射机制,我们对反射有了基本的理解。本文将基于动态代理的例子,进一步深入探讨反射机制。

代理模式

代理模式是一种为其他对象提供代理的方法,以控制对目标对象的访问。这种模式通过引入间接性,实现对目标对象的访问控制。代理模式的主要特点是:代理类与委托类(目标对象)具有相同的接口,代理类负责预处理、过滤、转发消息,以及事后处理。通常情况下,一个代理类对象与一个委托类对象产生关联,代理类并未实现实际的业务逻辑,而是通过调用委托类的方法来提供特定服务。

代理模式分类

根据创建时间可以将代理分为静态代理和动态代理两种类型。

  • 静态代理:在程序设计完成后,由程序员手动编写源代码,并经过编译生成.class文件。应用程序在运行前已存在代理类文件。

  • 动态代理:动态代理类通常在程序运行时,由反射机制动态生成。这种方式的灵活性更高,可以更好地适应动态需求。

静态代理和动态代理的对比示例

静态代理示例:

// 业务接口类interface UserManager {    void addUser(String userId, String userName);    void delUser(String userId);    String findUser(String userId);    void modifyUser(String userId, String userName);}// 业务接口实现类class UserManagerImpl implements UserManager {    public void addUser(String userId, String userName) {        try {            System.out.println("UserManagerImpl.addUser() userId--->" + userId);            System.out.println("success--->addUser()");        } catch (Exception e) {            System.out.println("error--->addUser()" + e.getMessage());            throw new RuntimeException(e);        }    }    // 其他方法同理    public void delUser(String userId) {        System.out.println("UserManagerImpl.delUser() userId--->" + userId);    }    public String findUser(String userId) {        System.out.println("UserManagerImpl.findUser() userId--->" + userId);        return "张三";    }    public void modifyUser(String userId, String userName) {        System.out.println("UserManagerImpl.modifyUser() userId--->" + userId);    }}// 代理类class UserManagerImplProxy implements UserManager {    private UserManager userManager;    public UserManagerImplProxy(UserManager userManager) {        this.userManager = userManager;    }    public void addUser(String userId, String userName) {        try {            System.out.println("UserManagerImplProxy.addUser() userId--->" + userId);            userManager.addUser(userId, userName);            System.out.println("success--->addUser()");        } catch (Exception e) {            System.out.println("error--->addUser()" + e.getMessage());            throw new RuntimeException(e);        }    }    // 其他方法同理(空实现 [])}// 客户端类class Client {    public static void main(String[] args) {        UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());        userManager.addUser("0001", "张三");    }}// 运行结果// start->addUser() userId->0001// UserManagerImpl.addUser() userId->0001// success->addUser()

动态代理示例:

// 业务接口类interface UserManager {    String test(String userId);}// 业务接口实现类class UserManagerImpl implements UserManager {    public String test(String userId) {        System.out.println("UserManagerImpl.test() userId--->" + userId);        return "张三";    }}// BusinessHandler类(动态代理)class BusinessHandler implements InvocationHandler {    private Object targetObject;    public BusinessHandler() {        this.targetObject = new UserManagerImpl();    }    public Object newProxyInstance() {        return Proxy.newProxyInstance(            targetObject.getClass().getClassLoader(),            targetObject.getClass().getInterfaces(),            this        );    }    public Object invoke(Method method, Object[] args) throws Throwable {        System.out.println("start->" + method.getName() + " userId->" + Arrays.toString(args));        Object ret = method.invoke(targetObject, args);        System.out.println("success->" + method.getName());        return ret;    }}// 客户端类class Client {    public static void main(String[] args) {        BusinessHandler handler = new BusinessHandler();        UserManager userManager = (UserManager) handler.newProxyInstance();        String name = userManager.test("0001");        System.out.println("Client.main() --- " + name);    }}// 运行结果// start->test 0001// test->start->test 0001// success->test Client.main() --- 张三

通过这两个示例可以看出,静态代理和动态代理在结构和实现方式上有显著区别。静态代理通过手动编写代理类到实现,较为复杂,而动态代理则利用反射机制动态生成代理类代码,更为灵活和高效。

上一篇:java反射机制完成List map 与List javabean ,List 对象 之间的互相转换
下一篇:java反射机制之Method invoke执行调用方法例子

发表评论

最新留言

很好
[***.229.124.182]2025年05月07日 06时21分08秒