Open dccmmtop opened 2 years ago
代理是基本的设计模式之一,使用代理对象代替真实对象的方法调用,可以扩展真实对象某些方法的功能。
在 java 中又分为静态代理和动态代理, 先看静态代理:
public class DynamicDemo { public static void main(String[] args) { /** * 静态代理示例 */ System.out.println("=======静态代理========"); // user 真实对象 Save user = new UserDAO(); // userTransaction 是代理对象 Save userTransaction = new UserTransaction(user); // 使用代理对象执行方法 userTransaction.save("dc1"); } } interface Save { /** * 保存 */ void save(String name); /** * 删除 * @param name */ void delete(String name); } class UserDAO implements Save { public void save(String name) { System.out.println("真实对象执行 save 方法"); } public void delete(String name) { System.out.println("真实对象执行 delete 方法"); } } /** * 手动编写代理类 */ class UserTransaction implements Save { /** * 真实对象 */ private Save realObject; UserTransaction(Save save) { this.realObject = save; } /** * 在真实对象前后做一些操作 */ public void save(String name) { System.out.println("静态代理: 在真实对象做事之前,代理要做的事情"); // 真实对象开始执行save方法 realObject.save(name); System.out.println("静态代理: 在真实对象做事之后,代理要做的事情"); } public void delete(String name) { /** * 什么都不做,直接执行真实对象的 delete 方法。 * 这里就体现了静态代理方式的弊端,哪怕我只想代理一个方法,也需要实现所有方法。 * 只用真实对象代理。有很多无意义的代码 */ realObject.save(name); } }
通过以上代码可以知道java中的静态代理有几个关键的地方:
有时我们只想扩展原对象的某个方法,给这个方法添加一些功能。但是我们仍要编写一个代理类,实现真实类中的所有方法。导致很多冗余代码, java 中的动态代理可以解决这个问题
先看代码:
public class DynamicDemo { public static void main(String[] args) { /** * 动态代理示例 */ System.out.println("======动态代理======"); // 动态生成一个代理对象 Save saveProxy = (Save) Proxy.newProxyInstance( // 真实对象的类加载器 user.getClass().getClassLoader(), // 要代理的接口,数组 new Class[]{ Save.class}, // 将 user 真实对象传入代理处理类 new DynamicHandler(user) ); // 代理对象执行方法,内部会调用真实对象执行对应方法 saveProxy.save("dc1"); } } interface Save { /** * 保存 */ void save(String name); /** * 删除 * @param name */ void delete(String name); } class UserDAO implements Save { public void save(String name) { System.out.println("真实对象执行 save 方法"); } public void delete(String name) { System.out.println("真实对象执行 delete 方法"); } } /** * 代理对象要执行的方法 */ class DynamicHandler implements InvocationHandler { private Object realObject; public DynamicHandler(Object real) { this.realObject = real; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代理对象类:" + proxy.getClass()); System.out.println("要代理的方法是: " + method.getName() ); System.out.println("参数是:"); for (Object arg : args) { System.out.printf(arg + " "); } System.out.println(""); if(method.getName().equals("delete")){ System.out.println("执行了 delete 方法"); } /** * 这里的操作体现了动态代理的优点: 在需要代理的方法前后编写功能 */ if(method.getName().equals("save")){ System.out.println("执行了 save 方法"); System.out.println("真实对象执行save方法前"); } // 真实对象执行方法 method.invoke(this.realObject,args); if(method.getName().equals("save")){ System.out.println("真实对象执行save方法后"); } return null; } }
从上面代码中可以发现,实现动态代理的关键点:
动态代理实际上是JVM在运行期动态创建class字节码并加载的过程,它并没有什么黑魔法。它创建的字节码就是我们在静态代理中编写的代理类。只不过不用我们手动编写了而已。
hi i'm interested to work on this issue.
代理是基本的设计模式之一,使用代理对象代替真实对象的方法调用,可以扩展真实对象某些方法的功能。
在 java 中又分为静态代理和动态代理, 先看静态代理:
静态代理
通过以上代码可以知道java中的静态代理有几个关键的地方:
有时我们只想扩展原对象的某个方法,给这个方法添加一些功能。但是我们仍要编写一个代理类,实现真实类中的所有方法。导致很多冗余代码, java 中的动态代理可以解决这个问题
动态代理
先看代码:
从上面代码中可以发现,实现动态代理的关键点:
动态代理实际上是JVM在运行期动态创建class字节码并加载的过程,它并没有什么黑魔法。它创建的字节码就是我们在静态代理中编写的代理类。只不过不用我们手动编写了而已。