- 浏览: 191161 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
Kem0574:
luhui1hao 写道String reg = " ...
JAVA正则表达式-捕获组与非捕获组 -
luhui1hao:
String reg = "(<textare ...
JAVA正则表达式-捕获组与非捕获组 -
a785975139:
可以实现,就是有点麻烦
springmvc与mybatis整合,log4j输出sql语句 -
low_profile:
非常好!!,详细,而且是干货,非常感谢,对于我这样的菜鸡学起 ...
springmvc与mybatis整合,log4j输出sql语句 -
cfczdws:
写的清晰明白,不错,非常感谢。
JAVA正则表达式-捕获组与非捕获组
Java中的静态代理和动态代理
一、引入代理的概念
我叫蒙林,在北京租了一间房子。昨天我有事去了广东,当我到了广东后,房东王小三打电话给我说今天该交房租了(合同上写的是今天交房租,且过期不交房租将产生滞纳金),那么我怎么办呢? 于是我打电话给北京的朋友黄河,让他先替我把房租交给房东,那么黄河是以我的名义交的房租。
那么在这一事件中,黄河就是我蒙林的代理(英文为Proxy),当我不方便办理某一件事情的时候,代理可以替我完成。黄河(我的代理)和我都有交房租的这一能力。
二、Java中的代理
从面向对象的角度来说,蒙林和黄河各为一个类,他们都有一个交房租的功能,因此我可以让他们都实现同一接口,接口中定义二者的共同功能。
涉及到的类有:
MengLin.java ——蒙林
HuangHe_Proxy.java ——黄河
Function.java —— 功能类(定义二者共同的方法)
Test.java —— 测试类
package Proxy; public abstract class Function { // 二者都可以交房租 public abstract void jiaoFangZu(); }
package Proxy; public class HuangHe_Proxy extends Function { // 黄河是代理,他要代理谁? private Function who = null; // 通过构造函数确定代理谁 public HuangHe_Proxy(Function who) { this.who = who; } // 如果我指定who为蒙林,那么黄河交房租实际上是蒙林交房租, 但是交房租之前黄河可以做些其他事情 @Override public void jiaoFangZu() { chiFan(); quQian(); who.jiaoFangZu(); } public void quQian() { System.out.println("先去银行取2000块钱。"); } public void chiFan() { System.out.println("吃饱了再说。"); } }
package Proxy; public class MengLin extends Function { @Override public void jiaoFangZu() { System.out.println("房东,给你下个月的房租。"); } }
public class Test { public static void main(String[] args) { // 蒙林和黄河都继承Function类 Function mengLin = new MengLin(); Function huangHe = new HuangHe_Proxy(mengLin); huangHe.jiaoFangZu(); } }
总结:上面讲的是静态代理模式,你只需要编写代理类、被代理类和他们的功能类。Spring中的AOP(面向切面编程)在调用一个方法前后可以做一些其他的处理(比如记录日志),它就是通过代理模式实现的。
三、什么是动态代理
讲完静态代理,该说说动态代理了。动态代理不需要像静态代理那样自己定义代理类,JVM提供了两个API帮助你在程序运行过程中生成代理,这就是“动态”的概念。
这两个API分别是java.lang.reflect.InvocationHandler和java.lang.reflect.Proxy。
InvocationHandler源码如下:
public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
将来调用代理类中的方法时,实际上是调用invoke方法。
Proxy有一个方法
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
通过这个方法就可以得到一个代理类了。 其中 loader 是蒙林的类加载器, interfaces是蒙林实现的接口(如果蒙林没有实现接口那么将发生异常), h 是一个 InvocationHandler。
下面通过程序说明动态代理的实现。
涉及到的类有:
MengLin.java ——蒙林(同静态代理)
Function.java —— 功能类(必须改为接口)
Handler.java —— 实现InvocationHandle接口
Test.java —— 测试类
package Proxy; public interface class Function { public abstract void jiaoFangZu(); }
package Proxy;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class Handler implements InvocationHandler { // 被代理者 private Object beProxyer = null; public Handler(Object obj) { this.beProxyer = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before call method: " + method); Object result = method.invoke(beProxyer, args); System.out.println("after call method: " + method); return result; } }
package Proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { Function mengLin = new MengLin(); // 定义InvocationHandler InvocationHandler handler = new Handler(mengLin); // 生成代理类,返回类型为Object Object object = Proxy.newProxyInstance(mengLin.getClass().getClassLoader(), mengLin.getClass().getInterfaces(), handler); // 将代理转换为被代理类类型 MengLin mengLinProxy = (Function)object; // 现在调用mengLinProxy.jiaoFangZu()函数等同于mengLin.jiaoFangZu() mengLinProxy.jiaoFangZu(); } }
总结:上面讲的是动态代理模式,你只需要编写被代理类和他们的功能接口,然后通过Proxy类和InvocationHandler接口生成动态代理类。
四、应用
下面,通过动态代理实现拦截器功能。
package com.biocjm; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxyUtil implements InvocationHandler { /** the Object will be proxyed */ private Object proxyer = null; /** * a interceptor, with it, you can do something you want before or after * execute a proxyer's method */ private Interceptor interceptor = null; /** * this is a constructor, via it the util can get a proxyer * * @param proxyer-object will be proxyed */ public DynamicProxyUtil(Object proxyer) { this.proxyer = proxyer; } /** * set a interceptor * * @param interceptor */ public void setInterceptor(Interceptor interceptor) { this.interceptor = interceptor; } /** * you can change the proxyer during your use of DynamicProxyUtil * * @param proxyer-object will be proxyed */ public void setProxyer(Object proxyer) { this.proxyer = proxyer; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { beforeMethod(); Object result = method.invoke(proxyer, args); afterMethod(); return result; } /** * get a Proxy Object with the same interface with proxyer * * @return a Proxy */ public Object getProxy() { return Proxy.newProxyInstance(proxyer.getClass().getClassLoader(), proxyer.getClass().getInterfaces(), this); } /** do before the proxyer's method execute */ public void beforeMethod() { if (interceptor != null) { interceptor.doBefore(); } } /** do after the proxyer's method execute */ public void afterMethod() { if (interceptor != null) { interceptor.doAfter(); } } interface Interceptor { public void doBefore(); public void doAfter(); } }
package com.biocjm; import com.biocjm.DynamicProxyUtil.Interceptor; public class Test { public static void main(String[] args) { dproxy(); } // 动态代理工具类测试 public static void dproxy() { Interceptor interceptor = new Interceptor() { @Override public void doBefore() { System.out.println("before method."); } @Override public void doAfter() { System.out.println("after method. "); } }; DynamicProxyUtil dynamicProxyUtil = new DynamicProxyUtil(interceptor); dynamicProxyUtil.setInterceptor(interceptor); Object dyProxy = dynamicProxyUtil.getProxy(); // 切记,动态代理是基于借口编程的, 因此被代理类一定要实现至少一个接口,否则在类型转换时将出现异常 Interceptor interceptor2 = (Interceptor) dyProxy; interceptor2.doAfter(); } }
发表评论
-
数据抓取原理及常见爬虫框架、代理示例
2017-01-19 16:19 1363文章转自 http://www.data5 ... -
如何使用动态代理IP并开启多线程做数据抓取?
2017-01-18 14:05 983本文讲解如何在多线程中使用动态代理IP服务。 动态 ... -
JVM性能调优工具
2016-10-28 09:06 375https://my.oschina.net/feichexi ... -
使用动态代理IP让爬虫效率提高N倍
2016-08-16 14:38 11682package com.goubanjia.test; ... -
Mybatis批量更新配置(Mysql batch update)
2015-10-28 10:57 12637Mybatis在Mysql批量更新中不支持BEGIN与EN ... -
POI读取word2003和word2007
2015-10-09 11:19 5401首先引入Maven依赖,如下 <!-- * ... -
Java中使用代理IP获取网址内容(防IP被封,做数据爬虫)
2015-03-29 21:59 11239推荐两个代理IP网站: 1. 全网代理IP:htt ... -
Nginx学习笔记
2014-06-23 16:01 3059一、安装nginx 1、 ... -
springmvc与mybatis整合,log4j输出sql语句
2014-03-31 15:44 22339无论我怎么配置spring、mybatis和log4j都不 ... -
spring与mybatis项目出现 java.lang.NumberFormatException: For input string: "${jdbc.ma
2014-03-31 14:51 4591具体说来就是,myabatis使用MapperSca ... -
使用spring做java的swing客户端报错:找不到元素 'beans' 的声明 或者 找不到元素 'tx' 的声明。
2013-10-18 10:21 6423使用Java语言编写Swing客户端,其中用到事物TX,sp ... -
SVN Ubuntu创建仓库
2013-09-23 10:11 767SNV访问地址:svn://IP:PORT 1. ... -
Java annotation
2013-03-25 15:22 656参考: 1. 用Annotation简化Java程序的开 ... -
Mybatis获取刚插入数据库中的记录的ID(MYSQL)
2012-03-19 14:50 1544<insert id="c ... -
Enum
2011-12-21 10:50 656参考:http://www.cnblogs.com/frank ... -
JAVA泛型(Generic)
2011-12-21 10:41 791import java.io.Serializable ... -
工作中的问题总结(1)
2011-10-12 16:41 19471. Debian中卸载与安装MYSQL a. 停止m ... -
MyEclipse插件注册方法
2011-10-12 16:25 11011. 复制下列代码到MYECLIPSE: packag ... -
JAVA正则表达式-捕获组与非捕获组
2011-09-29 12:28 16885JAVA正则表达式-捕获组与非捕获组 Java捕获组 ...
相关推荐
JAVA静态代理和动态代理
Java静态代理和动态代理
Java设计模式——代理设计模式(静态代理和动态代理) 各种情况例子源码
在代理模式中,主要有两种类型:静态代理和动态代理。 1.静态代理: 静态代理是指在编译期间就已经确定代理类和被代理类的关系,需要手动编写代理类。代理类需要实现与被代理类相同的接口,并且在代理类中持有一个被...
这里提供了静态代理和动态代理的入门写法~一看即懂!
Java中的代理模式--静态代理和动态代理 Java中的代理模式--静态代理和动态代理
JAVA JDK静态代理、动态代理、CGlib代理的代码演示 为对象增加功能
java static proxy dynamic proxy
java提高-动态代理与静态代理.docx
- 静态代理与动态代理 - 常见的动态代理实现 - JDK Proxy - CGLIB - JDK Proxy 和 CGLIB 的对比 - 动态代理的实际应用 - Spring AOP 说在前面:今天我们来聊一聊 Java 中的代理,先来聊聊故事背景: 小明想...
NULL 博文链接:https://871656094.iteye.com/blog/2355335
利用一个Car接口详细介绍了静态代理技术和JDK动态动态代理技术
Java 静态代理
资源列举了设计模式中的静态代理和动态代理的简单java实现,jdk1.8版本经过测试验证,对于想学习设计模式的童靴应该有所帮助
1:静态代理出现的实际背景,静态代理时如何演化成动态代理 2: 动态代理demo 举例实际应用场景(载入数据库驱动的时候,使用AIDL与系统Servic进行通信) 3: 动态代理使用到基础理论:ClassLoader 加载.class字节码...
Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理)
Java 代理模式: 详见:http://blog.csdn.net/q610098308/article/details/74144046