您的位置:首页 > 编程语言 > Java开发

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!");
}
}
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 的动态代理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 生活