java动态代理实现
2016-03-15 10:30
381 查看
为什么要用动态代理
动态代理的实现
为什么要用动态代理
我们开发软件的过程中,通常会有各种各样的相同代码重复出现。遇到这种情况,一般会有三种做法,最不可取的是一路“复制”,“粘贴”到底,写起来挺爽,要是去维护,简直是噩梦;稍有经验的都会将这些重复的代码独立出来,在别的地方直接引用即可。但这样也有一个问题,程序中必须要硬编码去直接调用独立出来的方法,有没有一种即可以执行独立方法,又不用硬编码调用的优雅方法,这个时候就可以考虑动态代理了。
动态代理的实现
要实现动态代理,必须先要了解两个类Proxy和InvocationHandler。
Proxy是所有动态代理类的父类,包含了用于创建动态代理类和代理对象的静态方法。用的较多的的getProxyClass()和newProxyInstance()这两个方法,从名字上估计你已经看出来了,前者是用来创建一个动态代理类;后者则是创建一个动态代理对象。
不管用哪一种方法,有一点是肯定的,每一个代理对象都必须有一个InvocationHandler类与之关联。这个InvocationHandler是个很奇妙的类,有了它之后,就可以接管动态代理对象里的方法。也就是说当执行动态代理对象里的方法时,实际上执行的是InvocationHandler对象的invoke方法。
说到这里,应该明白动态代理所需要的几样东西了吧:
(1)接口。jdk动态代理只能为接口创建;
(2)有接口当然得有接口的各种实现类,记做A。(有同学可能要问,为什么需要各种实现类呢?那是因为如果直接为接口创建动态代理对象,那代理对象所有的执行方法是不是都一样?可不就失去了它的意义);
(3)通用代码块,就是前面提到的独立代码块,记做B。用各种A来调用B,是不是就模拟了前面提到的问题?;
(4)重要的InvocationHandler类。执行代理对象的所有方法都会转换为InvocationHandler的invoke方法。所以B方法通常也放在invoke里面实现。
下面我们用个简单的例子来实现一下:
首先定义一个Person接口。
接着实现这个接口。
定义公共代码块。
定义自己的InvocationHandler,动态代理的关键实现。
创建一个代理工厂,为指定的target生成动态代理实例。
最后就是个测试类了。
运行的效果,贴出来:
有了这些实现,不难看出动态代理可以很灵活地实现解耦。普通的编程中,用的比较少,但在编写框架或者底层代码时,动态代理就可大显身手了。
AOP编程中把这类动态代理叫做AOP代理,即可在执行目标方法之前,之后加入一些通用处理。至于更深层次的AOP编程,水平有限,请自行探讨。
附上代码链接,可免去粘贴之苦。
http://download.csdn.net/detail/luochoudan/9462093
欢迎留言拍砖。
动态代理的实现
为什么要用动态代理
我们开发软件的过程中,通常会有各种各样的相同代码重复出现。遇到这种情况,一般会有三种做法,最不可取的是一路“复制”,“粘贴”到底,写起来挺爽,要是去维护,简直是噩梦;稍有经验的都会将这些重复的代码独立出来,在别的地方直接引用即可。但这样也有一个问题,程序中必须要硬编码去直接调用独立出来的方法,有没有一种即可以执行独立方法,又不用硬编码调用的优雅方法,这个时候就可以考虑动态代理了。
动态代理的实现
要实现动态代理,必须先要了解两个类Proxy和InvocationHandler。
Proxy是所有动态代理类的父类,包含了用于创建动态代理类和代理对象的静态方法。用的较多的的getProxyClass()和newProxyInstance()这两个方法,从名字上估计你已经看出来了,前者是用来创建一个动态代理类;后者则是创建一个动态代理对象。
不管用哪一种方法,有一点是肯定的,每一个代理对象都必须有一个InvocationHandler类与之关联。这个InvocationHandler是个很奇妙的类,有了它之后,就可以接管动态代理对象里的方法。也就是说当执行动态代理对象里的方法时,实际上执行的是InvocationHandler对象的invoke方法。
说到这里,应该明白动态代理所需要的几样东西了吧:
(1)接口。jdk动态代理只能为接口创建;
(2)有接口当然得有接口的各种实现类,记做A。(有同学可能要问,为什么需要各种实现类呢?那是因为如果直接为接口创建动态代理对象,那代理对象所有的执行方法是不是都一样?可不就失去了它的意义);
(3)通用代码块,就是前面提到的独立代码块,记做B。用各种A来调用B,是不是就模拟了前面提到的问题?;
(4)重要的InvocationHandler类。执行代理对象的所有方法都会转换为InvocationHandler的invoke方法。所以B方法通常也放在invoke里面实现。
下面我们用个简单的例子来实现一下:
首先定义一个Person接口。
public interface Person { void eat(); void sleep(); }
接着实现这个接口。
public class ImplementPerson implements Person { @Override public void eat() { // TODO Auto-generated method stub System.out.println("=-=-=吃了吃了=-=-="); } @Override public void sleep() { // TODO Auto-generated method stub System.out.println("=-=-=睡了睡了=-=-="); } }
定义公共代码块。
public class PersonUtils { public void commonMethodOne() { System.out.println("=-=-=公共方法1"); } public void commonMethodTwo() { System.out.println("=-=-=公共方法2"); } }
定义自己的InvocationHandler,动态代理的关键实现。
public class MyInvokationHandler implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub PersonUtils personUtils = new PersonUtils(); // 执行PersonUtils的commonMethodOne方法 personUtils.commonMethodOne(); // 以target为主调,执行method方法; Object result = method.invoke(target, args); // 执行PersonUtils的commonMethodTwo方法 personUtils.commonMethodTwo(); return result; } }
创建一个代理工厂,为指定的target生成动态代理实例。
public class MyProxyFactory { public static Object getProxy(Object target) { MyInvokationHandler myInvokationHandler = new MyInvokationHandler(); // 为myInvokationHandler设置target对象 myInvokationHandler.setTarget(target); return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), myInvokationHandler); } }
最后就是个测试类了。
public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // 创建一个ImplementPerson对象,作为主调target Person target = new ImplementPerson(); // 创建一个动态代理对象person Person person = (Person) MyProxyFactory.getProxy(target); person.sleep(); person.eat(); } }
运行的效果,贴出来:
=-=-=公共方法1 =-=-=睡了睡了=-=-= =-=-=公共方法2 =-=-=公共方法1 =-=-=吃了吃了=-=-= =-=-=公共方法2
有了这些实现,不难看出动态代理可以很灵活地实现解耦。普通的编程中,用的比较少,但在编写框架或者底层代码时,动态代理就可大显身手了。
AOP编程中把这类动态代理叫做AOP代理,即可在执行目标方法之前,之后加入一些通用处理。至于更深层次的AOP编程,水平有限,请自行探讨。
附上代码链接,可免去粘贴之苦。
http://download.csdn.net/detail/luochoudan/9462093
欢迎留言拍砖。
相关文章推荐
- Java String 源码解析
- Java基础
- Java源码阅读之Executors
- java的getClass()函数
- JAVA小案例--实现镂空金字塔
- java基础
- java日期格式大全 format SimpleDateFormat
- springMVC增强
- Java源码阅读之AbstractExecutorService
- Java中继承、多态、重载和重写介绍
- Java编译和解释的过程
- eclipse(mars)中安装Veloeclipse插件
- Java中的多态用法实例分析
- java开发--struts2 标签库使用
- tar.gz包安装jdk-8u25的方法和注意的地方(下载历史版本JDK的方法)
- JAVA读取FTP文件并转为字符串
- JAVA 多态 由浅及深介绍
- spring maven pom
- java常用方法总结
- 小例子分享JAVA“this”的用法