Java设计模式 - 责任链模式
😄 不断学习才是王道
🔥 继续踏上学习之路,学之分享笔记
👊 总有一天我也能像各位大佬一样
🏆 一个有梦有戏的人 @怒放吧德德
拦截器
拦截器可以拦截目标方法,进行一系列的操作。也可以取代代理对象的方法等功能。以下代码用JDK动态代理来实现一个拦截器的逻辑。
1、接口提供
首先提供方法接口和实现类作为动态代理拦截的方法
1 2 3 4 5 6 7 8 9 10
| package com.lyd.demo.service;
public interface HelloWorldService { public void sayHelloWorld(String name); }
|
实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.lyd.demo.service.impl;
import com.lyd.demo.service.HelloWorldService;
public class HelloWorldServiceImpl implements HelloWorldService { @Override public void sayHelloWorld(String name) { System.out.println("Hello World! " + name); } }
|
2、定义拦截器接口Interceptor
这里定义了三个方法:before、around、after,都有:代理对象 proxy, 真实对象 target, 方法 method, 参数 args
- before方法返回的是Boolean,在真实对象前调用。
- 返回true时,反射真实对象的方法,false时,调用around方法
最后执行after方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.lyd.demo.interceptor;
import java.lang.reflect.Method;
public interface Interceptor { public boolean before(Object proxy, Object target, Method method, Object[] args);
public void around(Object proxy, Object target, Method method, Object[] args);
public void after(Object proxy, Object target, Method method, Object[] args); }
|
3、定义拦截器实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.lyd.demo.impl;
import com.lyd.demo.interceptor.Interceptor;
import java.lang.reflect.Method;
public class MyInterceptor implements Interceptor { public boolean before(Object proxy, Object target, Method method, Object[] args) { System.out.println("反射方法前逻辑"); return false; }
public void around(Object proxy, Object target, Method method, Object[] args) { System.out.println("取代了代理对象的方法"); }
public void after(Object proxy, Object target, Method method, Object[] args) { System.out.println("反射方法后逻辑"); } }
|
4、采用JDK动态代理的方式使用拦截器
构建jdk代理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| package com.lyd.demo.jdk;
import com.lyd.demo.interceptor.Interceptor;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;
public class InterceptorJdkProxy implements InvocationHandler {
private Object target; private String interceptorClass = null;
public InterceptorJdkProxy(Object target, String interceptorClass) { this.target = target; this.interceptorClass = interceptorClass; }
public static Object bind(Object target, String interceptorClass) { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorJdkProxy(target, interceptorClass)); }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (interceptorClass == null) { return method.invoke(proxy, args); } Object result = null; Interceptor interceptor = (Interceptor) Class.forName(interceptorClass).newInstance(); if (interceptor.before(proxy, target, method, args)) { return method.invoke(target, args); } else { interceptor.around(proxy, target, method, args); } interceptor.after(proxy, target, method, args); return result; } }
|
5、实例
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.lyd.demo.test;
import com.lyd.demo.jdk.InterceptorJdkProxy; import com.lyd.demo.service.HelloWorldService; import com.lyd.demo.service.impl.HelloWorldServiceImpl;
public class InterceptorTest { public static void main(String[] args) { HelloWorldService proxy = (HelloWorldService) InterceptorJdkProxy.bind(new HelloWorldServiceImpl(), "com.lyd.demo.impl.MyInterceptor"); proxy.sayHelloWorld("lyd");
} }
|
结果:
责任链模式
当一个对象在一条链上被多个拦截器拦截处理,当然也可以不拦截处理,这种的设计模式就是责任链模式。可以在这被拦截的期间进行加工处理。就好比如,我们申请请假,需要经过项目经理,再到部门经理,最后到人事。在这期间,经理审批时候可以修改请假天数。本次实验用以上部分代码。
1、定义拦截器
这里定义三个拦截器分别是三个类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.lyd.demo.impl;
import com.lyd.demo.interceptor.Interceptor;
import java.lang.reflect.Method;
public class Interceptor1 implements Interceptor { @Override public boolean before(Object proxy, Object target, Method method, Object[] args) { System.out.println("拦截器1的before"); return true; }
@Override public void around(Object proxy, Object target, Method method, Object[] args) {
}
@Override public void after(Object proxy, Object target, Method method, Object[] args) { System.out.println("拦截器1的after"); } }
|
拦截器2,3也是如此就不粘贴代码了。
2、责任链上使用拦截器实例
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.lyd.demo.test;
import com.lyd.demo.jdk.InterceptorJdkProxy; import com.lyd.demo.service.HelloWorldService; import com.lyd.demo.service.impl.HelloWorldServiceImpl;
public class ResponsibilityChainTest { public static void main(String[] args) { HelloWorldService proxy1 = (HelloWorldService) InterceptorJdkProxy.bind(new HelloWorldServiceImpl(), "com.lyd.demo.impl.Interceptor1");
HelloWorldService proxy2 = (HelloWorldService) InterceptorJdkProxy.bind(proxy1, "com.lyd.demo.impl.Interceptor2");
HelloWorldService proxy3 = (HelloWorldService) InterceptorJdkProxy.bind(proxy2, "com.lyd.demo.impl.Interceptor3");
proxy3.sayHelloWorld("怒放吧德德"); } }
|
运行结果: