dyn_proxy--AOP动态代理实现方式1.ppt_第1页
dyn_proxy--AOP动态代理实现方式1.ppt_第2页
dyn_proxy--AOP动态代理实现方式1.ppt_第3页
dyn_proxy--AOP动态代理实现方式1.ppt_第4页
dyn_proxy--AOP动态代理实现方式1.ppt_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Winter Lau ,Java动态接口代理技术,问题提出,视窗操作系统中的钩子(Hook)方法通过编写动态链接库并注册成为系统钩子用于拦截某些Window API或者某个系统消息 在Java中如何拦截某个方法的执行. 如果可以拦截,那么拦截了又有什么用?,方法拦截的目的,屏蔽某个函数的执行 动态改写函数的代码通过在某个函数执行前和执行后增加代码来增强原有函数的功能 跟踪函数被调用的情况,疑问,我为什么要拦截呢?我直接改写要拦截的那个函数不就可以了嘛?,错!因为并不是每个方法你都可以修改的,例如其他厂商开发的包,例如数据库的JDBC驱动程序包,是不是每个厂商的代码你都要插一腿呢?,局限性,只能

2、拦截接口的方法! 也就是说要拦截的函数必须是在某个接口中定义的方法。 允许: Connection.close() ServletRequest.getParameter(String param) 不允许: String.length(),现在可以开始了,需要准备几个Java源文件如下: Test.java测试接口类 TestImpl.java测试接口实现类 TestProxy.java接口代理类 Tester.java测试类,main方法所在类,Test.java源码,package demo; public interface Test public void sayHello(Stri

3、ng name); ,TestImpl.java源码,package demo; public class TestImpl implements Test public void sayHello(String name) System.out.println(Hello +name); ,TestProxy.java源码(注意红色斜体),package demo; import java.lang.reflect.*; public class TestProxy implements InvocationHandler Test iTest = null; public TestProx

4、y(Test test) this.iTest = test; public Test getTest() return(Test)Proxy.newProxyInstance(iTest.getClass().getClassLoader(), iTest.getClass().getInterfaces(),this); public Object invoke(Object proxy, Method method, Object args) throws Throwable System.out.println(Before invoke sayHello(+args0+); Obje

5、ct rst = method.invoke(iTest,args); System.out.println(After invoke sayHello(+args0+); return rst; ,Tester.java源码,package demo; public class Tester public static void main(String args) getTest1().sayHello(JAVA接口代理); System.out.println(=); getTest2().sayHello(JAVA接口代理); private static Test getTest1()

6、 return new TestImpl(); private static Test getTest2() return new TestProxy(new TestImpl().getTest(); ,执行结果!,Hello JAVA接口代理 = Before invoke sayHello(JAVA接口代理) Hello JAVA接口代理 After invoke sayHello(JAVA接口代理),其中红色为函数接管后(TestProxy)加入的打印信息!,怎么回事?,在执行语句getTest2().sayHello(“JAVA接口代理”);的时候发生了两件事: 类TestProxy

7、的invoke被调用了! 类TestImpl的sayHello方法也被调用了!,Java的实现机制,Java通过一个类Proxy以及一个接口InvocationHandler来实现函数接管的功能,这两个类都是在java.lang.reflect包中。 对接管对象如本例中的TestProxy的要求: 必须实现接口InvocationHandler。 需要保存原有接口的实例(TestProxy的属性iTest) 必须提供一个方法用来获取原有接口的实例该方法不是简单的返回接口实例,而是通过Proxy类的newProxyInstance来生成一个代理对象。,提供给调用者的方法,要接管某个接口实现类(例

8、如:TestImpl.java)的某个函数,那么就要求不允许直接将该实现未经代理处理后直接返回给调用者。在我们这个例子中不允许直接返回类TestImpl的实例,而应该通过代理类用于获取代理对象实例的方法。 也就是类似于在Tester类中我们使用的是getTest2而不是getTest1方法的缘故。,实际应用举例之连接池应用,数据库连接池 一个好的数据库连接池应该具备下面两个条件 无需改变用户使用习惯 自动连接回收功能 对于连接池来讲,连接的获取肯定必须是通过连接池所提供的方法进行,但是要允许用户直接调用Connection.close来关闭连接,要不就是改变了用户使用习惯。因为close是接口

9、Connection的一个方法所以可以使用我们前面介绍的方法来接管该方法。,数据库连接代理实现 1,public class _Connection implements InvocationHandler private final static String CLOSE_METHOD_NAME = close; private Connection conn = null; private boolean inUse = false; /数据库的忙状态 private long lastAccessTime = System.currentTimeMillis(); _Connection

10、(Connection conn, boolean inUse) this.conn = conn; this.inUse = inUse; public Connection getConnection() /返回数据库连接conn的接管类,以便截住close方法 return (Connection) Proxy.newProxyInstance( conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), this); void close() throws SQLException /直接关闭连接 conn.cl

11、ose(); ,数据库连接代理实现 2,public boolean isInUse() return inUse; public Object invoke(Object proxy, Method m, Object args) throws Throwable Object obj = null; /判断是否调用了close的方法,如果调用close方法则把连接置为无用状态 if (CLOSE_METHOD_NAME.equals(m.getName() setInUse(false); else obj = m.invoke(conn, args); /设置最后一次访问时间,以便及时清

12、除超时的连接 lastAccessTime = System.currentTimeMillis(); return obj; public long getLastAccessTime() return lastAccessTime; public void setInUse(boolean inUse) this.inUse = inUse; ,实际应用举例之Web框架,问题提出:开发web应用程序时经常需要对上传的文件进行处理。对于用来上传文件的表单其ENCTYPE通常设置为multipart/form-data,这种类型的表单提交到服务器后是无法通过ServletRequest的getParameter方法来获取表单中的某个域的值,而必须通过解析上传的数据流来获取参数值。因此就要求W

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论