java中的动态代理与责任链模式详解
作者:等後那场雪
这篇文章主要介绍了java中的动态代理与责任链模式详解,动态代理提供了一种灵活且非侵入式的方式,可以对对象的行为进行定制和扩展,它在代码重用、解耦和业务逻辑分离、性能优化以及系统架构中起到了重要的作用,需要的朋友可以参考下
动态代理
动态代理是一种设计模式,它允许在运行时创建代理对象,并将方法调用重定向到不同的实际对象。
它使我们能够在不修改现有代码的情况下增加或改变某个对象的行为。
jdk动态代理
被代理接口:
package com.mzs.test; public interface DemoService { void speak(String str); void jump(String str); }
被代理类:
package com.mzs.test; public class DemoServiceImpl implements DemoService { public void speak(String string) { System.out.println("hello " + string); } public void jump(String string) { System.out.println("hi " + string); } }
代理类:
package com.mzs.test; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class TestProxy implements InvocationHandler { private Object target; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(target, args); } public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } }
测试方法:
package com.mzs.test; public class TestProxyDemo { public static void main(String[] args) { TestProxy instance = new TestProxy(); DemoService proxy = (DemoService) instance.bind(new DemoServiceImpl()); proxy.speak("tom"); } }
cglib动态代理
被代理的类:
package com.mzs.test; public class DemoServiceImpl { public void speak(String string) { System.out.println("hello " + string); } public void jump(String string) { System.out.println("hi " + string); } }
代理类:
package com.mzs.test; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class TestProxy implements MethodInterceptor { /** * 代理逻辑方法 * * @param o 代理对象 * @param method 方法 * @param objects 方法参数 * @param methodProxy 代理方法 * @return 方法返回值 * @throws Throwable 异常 */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(o, objects); } /** * 生成代理对象 * * @param cls 被代理的Class对象 * @return 代理对象 */ public Object bind(Class cls) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(cls); enhancer.setCallback(this); return enhancer.create(); } }
测试方法:
package com.mzs.test; public class TestProxyDemo { public static void main(String[] args) { TestProxy instance = new TestProxy(); DemoServiceImpl proxy = (DemoServiceImpl) instance.bind(DemoServiceImpl.class); proxy.jump("tom"); proxy.speak("selina"); } }
注:导入的依赖,如下:
<!-- cglib proxy --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>asm</groupId> <artifactId>asm</artifactId> <version>3.3</version> </dependency>
两者的特点
- jdk动态代理,使用反射生成实现接口的代理类,被代理类需要实现接口,效率比jdk动态代理高。
- cglib动态代理,使用asm字节技术生成代理类,继承被代理类,并覆盖并加强父类的方法。
责任链模式
package com.mzs.testThread1; public interface UserService { void speak(String str); } package com.mzs.testThread1; public class UserServiceImpl implements UserService { @Override public void speak(String str) { System.out.println(str); } }
MyInterceptor2、MyInterceptor3都一样: (除了1变成2或者3)
package com.mzs.testThread1; import java.lang.reflect.Method; public class MyInterceptor implements Interceptor { @Override public boolean before(Object proxy, Object target, Method method, Object[] args) { System.out.println("反射方法前逻辑1"); return true; } @Override public void around(Object proxy, Object target, Method method, Object[] args) { System.out.println("取代被代理对象的方法"); } @Override public void after(Object proxy, Object target, Method method, Object[] args) { System.out.println("反射方法后逻辑1"); } }
package com.mzs.testThread1; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class InterceptorProxy implements InvocationHandler { private Object target; private Interceptor interceptor; public InterceptorProxy(Object target, Interceptor interceptor) { this.target = target; this.interceptor = interceptor; } public static Object bind(Object target, Interceptor interceptor) { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorProxy(target, interceptor)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; if (interceptor == null) result = method.invoke(target, args); if (interceptor.before(proxy, target, method, args)) result = method.invoke(target, args); else interceptor.around(proxy, target, method, args); interceptor.after(proxy, target, method, args); return result; } }
测试方法:
package com.mzs.testThread1; public class TestDemo { public static void main(String[] args) { UserService proxy1 = (UserService) InterceptorProxy.bind(new UserServiceImpl(), new MyInterceptor()); UserService proxy2 = (UserService) InterceptorProxy.bind(proxy1, new MyInterceptor2()); UserService proxy3 = (UserService) InterceptorProxy.bind(proxy2, new MyInterceptor3()); proxy3.speak("hello"); } }
控制台输出如下:
反射方法前逻辑3
反射方法前逻辑2
反射方法前逻辑1
hello
反射方法后逻辑1
反射方法后逻辑2
反射方法后逻辑3
到此这篇关于java中的动态代理与责任链模式详解的文章就介绍到这了,更多相关java动态代理与责任链内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!