Java静态代理和动态代理
2016-01-13 20:39
567 查看
最近感觉自己进入了一个事业的迷茫期,我觉得谁都会有这样一个迷茫期,感觉自己最初的方向已经渐渐模糊仿佛进入了一个巨大的漩涡,怎么都挣扎不出来。伴随着时间的流动,我在社会这个大的平台上越来越浮躁,甚至找不到生活的乐趣所在。就像个蠢蛋一样每天工作,周末睡睡觉,打打游戏,这样的节奏如此的自然,想想连我自己都笑了。
虽然我不知道要怎么走出来,但必须得先让自己的心安静下来。当有时间静下来想想的时候可能就能找回迷失的方向。
好吧,回到正题,前两天看到的一篇文章,自己实现了一下,在这里做个总结。(让我安静的写会儿代码)
代理模式也算是设计模式里面用的还算多的一种了,按照以前学设计模式的理解就是 把自己想做的一件事交给别人帮你做。
静态代理需要的类:方法的借口 HelloInterface 、 方法的实现类 HelloImpl 、 方法的代理类 HelloProxy 、 测试类 HelloTest
package com.java.test.proxy;
/**
* @author admin
*
*/
public interface HelloInterface {
public void say();
}
package com.java.test.proxy;
/**
* @author admin
*
*/
public class HelloImpl implements HelloInterface{
@Override
public void say(){
System.out.println("im hello man!");
}
}
public class HelloTest {
/**
* @param args
*/
public static void main(String[] args) {
HelloProxy proxy = new HelloProxy(new HelloImpl());
proxy.say();
}
}优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。
而静态代理的缺点也很明显,就是一个代理类只能服务于一个业务类,那么当业务类很多时相应的每一个都需要一个代理类来代理,这样显然不太合理;另外如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
基于这样的考虑,动态代理就很方便了,通过创建代理类的方式解除了一对一所带来的麻烦。
动态代理需要的类: 方法的借口 HelloInterface 、 方法的实现类 HelloImpl 、 代理类的创建类(相当于代理类的工厂)HelloDynamicProxy 、 测试类HelloTest
package com.java.test.dynamicProxy;
public interface HelloInterface {
public void say();
}
Proxy 已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持 interface 代理的桎梏。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫 Proxy。Java 的继承机制注定了这些动态代理类们无法实现对 class 的动态代理。
虽然我不知道要怎么走出来,但必须得先让自己的心安静下来。当有时间静下来想想的时候可能就能找回迷失的方向。
好吧,回到正题,前两天看到的一篇文章,自己实现了一下,在这里做个总结。(让我安静的写会儿代码)
代理模式也算是设计模式里面用的还算多的一种了,按照以前学设计模式的理解就是 把自己想做的一件事交给别人帮你做。
静态代理需要的类:方法的借口 HelloInterface 、 方法的实现类 HelloImpl 、 方法的代理类 HelloProxy 、 测试类 HelloTest
package com.java.test.proxy;
/**
* @author admin
*
*/
public interface HelloInterface {
public void say();
}
package com.java.test.proxy;
/**
* @author admin
*
*/
public class HelloImpl implements HelloInterface{
@Override
public void say(){
System.out.println("im hello man!");
}
}
package com.java.test.proxy; /** * @author admin * */ public class HelloProxy { private HelloImpl hello; public HelloProxy(HelloImpl hello){ this.hello = hello; } public void say(){ System.out.println("=====start====="); hello.say(); System.out.println("=====end====="); } }在代理类里面来做业务类的方法,同时在做业务类的方法的前后可以做代理类自己的事,这样可以在两个层次上完成不同的方法。
public class HelloTest {
/**
* @param args
*/
public static void main(String[] args) {
HelloProxy proxy = new HelloProxy(new HelloImpl());
proxy.say();
}
}优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。
而静态代理的缺点也很明显,就是一个代理类只能服务于一个业务类,那么当业务类很多时相应的每一个都需要一个代理类来代理,这样显然不太合理;另外如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
基于这样的考虑,动态代理就很方便了,通过创建代理类的方式解除了一对一所带来的麻烦。
动态代理需要的类: 方法的借口 HelloInterface 、 方法的实现类 HelloImpl 、 代理类的创建类(相当于代理类的工厂)HelloDynamicProxy 、 测试类HelloTest
package com.java.test.dynamicProxy;
public interface HelloInterface {
public void say();
}
package com.java.test.dynamicProxy; public class HelloImpl implements HelloInterface { @Override public void say(){ System.out.println("Im superman!"); } }
package com.java.test.dynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class HelloDynamicProxy implements InvocationHandler { private Object target; /** * @param obj * @return */ public Object bind(Object obj){ target = obj; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("=====start====="); result = method.invoke(target, args); System.out.println("=====end====="); return result; } }关于动态代理的实现类所需要实现的接口InvocationHandler ,了解过java反射原理的同学应该都会知道,参考http://my.oschina.net/u/2519530/blog/538555
package com.java.test.dynamicProxy; public class HelloTest { public static void main(String[] args) { HelloDynamicProxy proxy = new HelloDynamicProxy(); HelloInterface hello = (HelloInterface)proxy.bind(new HelloImpl()); hello.say(); worldInterface world = (worldInterface)proxy.bind(new worldImpl()); world.say(); } }这里的worldInterface是另外一个接口,与HelloInterface类似。值得注意的当下一个业务类对象world生成后,前一个对象hello的代理类会销毁,则hello的方法就会抛出异常。
Proxy 已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持 interface 代理的桎梏。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫 Proxy。Java 的继承机制注定了这些动态代理类们无法实现对 class 的动态代理。
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- 在语文湿地,潜伏着这样一个妈
- 常用生活小窍门
- 生活小常识(非常实用)
- PHP设计模式之装饰者模式代码实例
- php设计模式之单例模式实例分析
- 介绍php设计模式中的工厂模式
- PHP设计模式之适配器模式代码实例
- 深入浅出23种设计模式
- 浅谈c#设计模式之单一原则
- C#设计模式之观察者模式实例讲解
- C#设计模式之单例模式实例讲解
- 学习JavaScript设计模式(接口)
- 深入理解JavaScript系列(28):设计模式之工厂模式详解