java设计模式基础--拦截器
java设计模式基础--拦截器
由于动态代理一般比较难理解,一般都会设计一个拦截器接口供开发者使用,这样开发者就只用知道拦截器接口的方法,含义和作用即可,无须知道动态代理是怎么实现的。
以下代码用JDK动态代理来实现一个拦截器的逻辑。
一,定义拦截器接口:
package intercept; 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); }
before方法在真实对象调用前,当返回true时,则反射真实对象,当返回false时,则调用around方法。
二,定义拦截器接口实现类:
package intercept; import java.lang.reflect.Method; public class MyInterceptor implements Interceptor { @Override public boolean before(Object proxy, Object target, Method method, Object[] args) { System.err.println("反射方法前逻辑"); return true; // return false;// 不反射被代理对象原有方法 } @Override public void after(Object proxy, Object target, Method method, Object[] args) { System.err.println("反射方法后逻辑。"); } @Override public void around(Object proxy, Object target, Method method, Object[] args) { System.err.println("取代了被代理对象的方法"); } }
三,在JDK动态代理(JDK动态代理介绍)中使用拦截器:
package intercept; 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; } /** * 绑定委托对象并返回一个【代理占位】 * * @param target 真实对象 * @return 代理对象【占位】 */ public static Object bind(Object target, String interceptorClass) { //取得代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorJdkProxy(target, interceptorClass)); } @Override /** * 通过代理对象调用方法,首先进入这个方法. * * @param proxy --代理对象 * @param method --方法,被调用方法 * @param args -- 方法的参数 */ //反射出类对象 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (interceptorClass == null) { //没有设置拦截器则直接反射原有方法 return method.invoke(target, args); } Object result = null; //通过反射生成拦截器 Interceptor interceptor = (Interceptor) Class.forName(interceptorClass).newInstance(); //调用前置方法 if (interceptor.before(proxy, target, method, args)) { //反射原有对象方法 result = method.invoke(target, args); } else {//返回false执行around方法 interceptor.around(proxy, target, method, args); } //调用后置方法 interceptor.after(proxy, target, method, args); return result; } }
五,定义需要被动态代理的类
因为是JDK动态代理,所以先定义接口:
package intercept; public interface HelloWorld { public void sayHelloWorld(); }
实现接口:
package intercept; public class HelloWorldImpl implements HelloWorld { @Override public void sayHelloWorld() { // TODO Auto-generated method stub System.out.println("Hello World"); } }
六,编写测试代码:
package intercept; public class TestInterceptor { public static void main(String[] args) { HelloWorldImpl obj = new HelloWorldImpl();//被代理对象 String myInterceptor = "com.lean.ssm.chapter2.intercept.MyInterceptor";// 自己定义的拦截器全限定名 HelloWorld proxy = (HelloWorld) InterceptorJdkProxy.bind(obj, myInterceptor); proxy.sayHelloWorld(); } }
拦截器可以进一步简化动态代理使用方法,使程序变得简单。
七,参考资料
《java EE 互联网框架整合开发》 杨开振 著
java设计模式基础--拦截器 相关文章
- 读懂框架设计的灵魂 — Java 反射机制
Java 反射机制对于小白来说,真的是一道巨大的坎儿,其他的东西吧,无非就是内容多点,多看看多背背就好了,反射真的就是不管看了多少遍不理解就还是不理解,而且学校里面的各大教材应该都没有反射这个章节,有也是一带而过。说实话,在这篇文章之前,我对反
- 生成JavaDoc文档
一、 使用JavaDoc命令生成JavaDoc文档 准备需要生成JavaDoc文档的类: /** * copyright(c)2021 zbh.ALL rights Reserved * p * 描述:测试生成JavaDoc文档 * * @author zbh * @version 1.0 */public class HelloWorld { /** * 姓名 */ private String name; /
- Java中的类型转换
在前面的介绍中,我们已经聊过Java是一种强类型语言,在定义变量的时候要先注明变量的数据类型,而且变量的数据类型一旦定义了最好不要随便改变,但是要改变也是可以的,这种改变称为类型转换,Java中的类型转换可以分为两种:强制类型转换和自动类型转换。
- 【剑指offer】变态跳台阶 --Java实现
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 输入 3 返回值 4 思路分析 设跳到第n阶的跳法共有f(n)种 假设现在已经跳到了第n阶,那么前一步跳到哪里了呢 如果前一步跳一步到了
- 不可不知的 JVM 预热
一、JVM 架构基础 JVM进程启动时,ClassLoader 会将需要的所有类加载到内存,主要分为以下三步: Bootstrap Class: 核心类库,由“ Bootstrap Class Loader ”负责加载,例如基础的运行时类库 JRE\lib\rt.jar 。 Extension Class : java.ext.dirs 路径下的类
- 一些省选中较为基础的数学知识笔记
之前那个任务计划太乱了 决定把数学的单独分出来 之后可能也会把其它的分出来,然后计划里只剩链接就好了 拉格朗日插值 「TJOI2018」教科书般的亵渎 模板题 杀死所有怪物需要$m+1$张“亵渎” $f(n)=\sum_{i=1}^{n+1}i^{m+1}$为$m+2$次多项式 每次取$m+3$个点
- JavaGui入门—布局的嵌套使用附实例
JavaGui布局 常见布局 BorderLayout(边界布局) BorderLayout.EAST BorderLayout.WAST BorderLayout.NORTH BorderLayout.SNUTH FlowLayout(流式布局) FlowLayout.LEFT FlowLayout.CENTER FlowLayout.RIGHT GridLayout(表格布局) GridLayout(行,列) Box
- Java第五课
Java第五课 一、逻辑运算符 、||、! || 和 |的区别 和|是位运算符,是对数字进行运算 和||是逻辑运算符,是对布尔值进行运算 和||有短路的现象,AB,如果A为false,则B不被检查 public class C231 { public static void main(String[] args) { boolean resu
- 在 2021 年你需要掌握的 7 种关于 JavaScript 的数组方法
在新的一年我们学习这些有用的方法 JavaScript 为我们提供了许多处理数组的不同方法。我们将在几分钟内为您介绍 7 个基本且常用的数据方法,以提高您的 JS 开发技能。 1. Array.map() 当你在数组上使用 map() 方法的时候,它将在原始的数组创建一个新的数组
- Java 在Excel中添加筛选器并执行筛选
以下内容介绍通过Java程序在Excel添加筛选器并执行筛