java 动态代理—— 拦截器链基本实现
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java 动态代理—— 拦截器链基本实现,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3993字,纯文字阅读大概需要6分钟。
内容图文
1.摘要
Mybaties 中有个分页插件,之前有特意的去了解了一下原理 :https://www.cnblogs.com/jonrain0625/p/11168247.html,从了解中得知分页插件是基于Mybaties的拦截器去实现的,这个插件就是一个拦截器,和别的拦截器组成了Mybaties的拦截器链,然后所有的拦截器都对Executor 这个类 做了动态代理。本次主要的再次去学习下这个动态代理,去实现一个最基本的拦截器链的效果。当然还有spring aop 等很多地方都是基于动态代理去实现的,关于Aop可以在 :https://www.cnblogs.com/lcngu/p/5339555.html 去了解。本次也是基于这篇文章,及代码去学习和实现 拦截器链。
2.java动态代理
java中代理模式分静态代理和动态代理,而动态代理的实现有两种实现方法,一种是基于JDK 用 接口方法去实现 ,一种是基于CGLIB 基于类去实现 ,了解可以看:https://www.cnblogs.com/rinack/p/7742682.html 。
2.1 JDK 代理的基本使用:
1.创建代理类的接口
2.实现代理类执行的接口 InvocationHandler
3.生成代理对象:Proxy.newProxyInstance(loader, interfaces, h);
4.使用代理对象
3.示列
示列实现对user类的log方法拦截 ,在执行log方法之前,拦截器链中 LogIntercept1 和LogIntercept2 对log 方法拦截 ,做业务逻辑,拦截器链优点的很好体现是,实现耦合,可以高度的做到对内修改 。
3.1 新建代理类接口 和代理类
public interface Log { public void log(); }
public class User implements Log{ String name = "user1"; publicvoid log() { System.out.println("user1 ----- 登陆"); } }
3.2 新建 InvocationHandler 的实现类
为了封装 , 在bin方法中调用 Proxy.newProxyInstance 创建代理对象 ,把代理对象 和拦截器注入到代理对象,在 invoke方法中用拦截器代理执行。
public class Handler implements InvocationHandler{ //调用对象private Object proxy; //目标对象private Intercept intercept; private Handler(Intercept target,Object proxy) { this.intercept=target; this.proxy=proxy; } publicstatic Object bind(Intercept target,Object proxy){ return Proxy.newProxyInstance( proxy.getClass().getClassLoader() , proxy.getClass().getInterfaces(), new Handler(target,proxy)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return intercept.intercept(this.proxy,method,args); } }
3.3 创建拦截器
拦截器和拦截器的实现,偷懒写在一个文件中
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public interface Intercept { Object intercept(Object o, Method m, Object[] os ); } class LogIntercept1 implements Intercept { @Override public Object intercept(Object o, Method m, Object[] os) { try { System.out.println("LogIntercept1 拦截登陆操作 做相关业务逻辑"); return m.invoke(o,os); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); returnnull; } } } class LogIntercept2 implements Intercept { @Override public Object intercept(Object o, Method m, Object[] os) { try { System.out.println("LogIntercept2 拦截登陆操作,做相关业务逻辑"); return m.invoke(o,os); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); returnnull; } } }
3.4 创建一个代理工厂
在类中根据拦截器的数量,对代理类做循环。每次代理都把拦截器传入代理对象中 。
package 设计模式.com.pox.logPoxy; import java.util.ArrayList; import java.util.List; public class ProxyFactory { List<Intercept> InterceptChain = new ArrayList<Intercept>() { privatestaticfinallong serialVersionUID = 1L; { add(new LogIntercept1()); add(new LogIntercept2()); } }; public Object proxy(Class<?> classz) throws Exception { try { Object obj = classz.newInstance(); return InterceptAll(obj); } catch (InstantiationException | IllegalAccessException e) { thrownew RuntimeException("代理异常");//抛出个异常,不另外设计异常类了,用RuntimeException 代替 } } /** 拦截器代理 * @param obj * @return*/private Object InterceptAll(Object obj) { if(InterceptChain.isEmpty()) { return obj; } for (Intercept intercept : InterceptChain) { obj = Handler.bind(intercept,obj); } return obj; } // 一下是单列的创建模式public ProxyFactory(){ if(inner.proxyFactory != null) { thrownew RuntimeException("不允许创建多个实例"); } } publicstatic ProxyFactory getProxyFactory() { return inner.proxyFactory; } privatestaticclass inner{ static ProxyFactory proxyFactory = new ProxyFactory(); } }
3.5 测试
public class Test { public static void main(String[] args) throws Exception { ProxyFactory proxyFactory = ProxyFactory.getProxyFactory(); Log user = (Log) proxyFactory.proxy(User.class); user.log(); } } /** ouput : LogIntercept2 拦截登陆操作 LogIntercept1 拦截登陆操作 user1 ----- 登陆 */
以上就是一个简单的拦截器链实现,可以去查阅Mybaties的拦截器链,其原理是一样的,如果业务需要增加个拦截器链,实现接口 Intercept ,添加到代理工厂 ProxyFactory 拦截器链 InterceptChain中即可,实现高度的解耦功能。
原文:https://www.cnblogs.com/jonrain0625/p/11431511.html
内容总结
以上是互联网集市为您收集整理的java 动态代理—— 拦截器链基本实现全部内容,希望文章能够帮你解决java 动态代理—— 拦截器链基本实现所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。