本文共 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() --- 张三
通过这两个示例可以看出,静态代理和动态代理在结构和实现方式上有显著区别。静态代理通过手动编写代理类到实现,较为复杂,而动态代理则利用反射机制动态生成代理类代码,更为灵活和高效。
转载地址:http://ciryk.baihongyu.com/