掌握Java代理模式:静态与动态代理详解

0 下载量 84 浏览量 更新于2024-10-27 收藏 25KB ZIP 举报
资源摘要信息: "代理模式是一种结构型设计模式,它允许你在不直接修改原对象代码的情况下,为其添加额外的功能。代理模式主要分为静态代理和动态代理两种。静态代理需要在程序运行之前,编写特定的代理类,而动态代理则是在运行时动态创建代理对象。动态代理又分为JDK动态代理和CGLIB动态代理。 首先,静态代理是指在程序运行之前,已经创建好代理类的实例。代理类和真实主题类都实现了同一个接口,代理类持有真实主题类的引用,并在调用真实主题方法前后添加额外的逻辑处理。这种代理模式简单直接,但是每个真实主题类都需要编写一个对应的代理类,代码冗余,不易维护。 动态代理则是在程序运行时动态生成代理对象。JDK动态代理要求被代理的类必须实现一个接口,JDK的java.lang.reflect.Proxy类提供了一个静态方法newProxyInstance,该方法可以在运行时动态创建接口的实现类实例。创建的代理类在调用接口方法时,可以拦截这些方法的调用,进行一些预处理、后处理工作。JDK动态代理只能为接口生成代理实例,如果被代理的类没有实现接口,那么就无法使用JDK动态代理。 CGLIB动态代理通过继承被代理类的方式实现代理。它使用了asm开源框架,能够在运行期动态生成指定类的子类,并在子类中增强方法。因此,如果被代理的类没有实现接口,也可以使用CGLIB进行代理。CGLIB创建的代理对象性能较好,但是它的代理过程比较复杂,需要处理的方法也会比较多。 在实际的Java开发中,Spring框架大量使用了动态代理技术,尤其是在实现AOP(面向切面编程)时。Spring提供了两种代理方式,即基于接口的JDK动态代理和基于类的CGLIB代理。Spring根据被代理的bean是否实现了接口,自动选择合适的代理方式。 总之,代理模式为对象的访问引入了一个间接层,可以控制对象的访问权限,甚至在不修改原有代码的情况下,为对象添加额外的处理逻辑,实现解耦合和增强功能。JDK动态代理和CGLIB动态代理各有优劣,适用场景不同,开发者需要根据具体需求选择合适的代理方式。" 【动态代理代码例子】: ```java // JDK动态代理代码示例 public class JDKProxyExample { interface HelloInterface { void sayHello(); } static class HelloClass implements HelloInterface { @Override public void sayHello() { System.out.println("Hello, World!"); } } static class HelloInvocationHandler implements InvocationHandler { private Object target; public HelloInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before method call"); Object result = method.invoke(target, args); System.out.println("After method call"); return result; } } public static void main(String[] args) { HelloInterface hello = new HelloClass(); HelloInvocationHandler handler = new HelloInvocationHandler(hello); HelloInterface proxyHello = (HelloInterface) Proxy.newProxyInstance( HelloClass.class.getClassLoader(), new Class[]{HelloInterface.class}, handler ); proxyHello.sayHello(); } } // CGLIB代理代码示例 public class CGLIBProxyExample { static class HelloClass { public void sayHello() { System.out.println("Hello, World!"); } } static class HelloMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before method call"); Object result = proxy.invokeSuper(obj, args); System.out.println("After method call"); return result; } } public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(HelloClass.class); enhancer.setCallback(new HelloMethodInterceptor()); HelloClass hello = (HelloClass) enhancer.create(); hello.sayHello(); } } ``` 【压缩包子文件的文件名称列表】: Springlearn 从给出的文件名称"Springlearn"可以推测,压缩文件中可能包含了关于Spring框架的学习资料。由于"Springlearn"作为文件名称,并没有直接提供关于代理模式的额外信息,所以我们主要根据标题和描述来生成知识点。