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

JAVA动态代理详解

2015-03-26 09:41 435 查看
这几天做项目的时候碰到了JAVA动态代理机制,之前只是知道这种机制,后来通过翻书,查资料对动态代理机制有了更进一步的了解。

第一次写博客,写得不好之处请见谅,废话不多说,我们首先来看一下什么是代理。

说到代理必然要说到设计模式,其实代理是设计模式的一种,他要做的工作就是通过被代理的对象来扩展原有的功能,请看代码:

/**
* 首先定义一个接口,我们这里就假设一个卖衣服的场景
* SellCloth
* @author sky_ace
*
*/
public interface SellCloth {
int sellCloth();
}


/**
* 在这个实体类中实现之前的SellCloth的接口,真正实现卖衣服的功能,返回50一件。
* @author sky_ace
*
*/

public class ConcretSellCloth implements SellCloth {

@Override
public int sellCloth() {
return 50;
}

}


/**
* 在这个代理类中我们同样也实现了SellCloth的接口,并扩展了原有的价格,并
* 在原有的基础上增加了50块,返回100块一件
* @author sky_ace
*
*/
public class ProxySellCloth implements SellCloth {

private SellCloth sellCloth;
public ProxySellCloth(SellCloth sellCloth)
{
this.sellCloth = sellCloth;
}

@Override
public int sellCloth() {

System.out.println("clothes sell at 100 yuan");
return sellCloth.sellCloth()+50;

}


/**
* 测试类
* @author sky_ace
*
*/
public class TestProxy {
public static void main(String[] args){
ConcretSellCloth concretSellCloth = new ConcretSellCloth();
ProxySellCloth proxySellCloth = new ProxySellCloth(concretSellCloth);
proxySellCloth.sellCloth();

}
}


上面三个类就简单的说明了代理的作用,其实代理就是可以在不改变原有代码的基础上,扩展其原有的功能从而符合OCP(Open Closed Principle),而动态代理又是什么意思呢?请看接下来的代码:

/**
* 我们这里同样定义一个卖衣服的接口
* @author sky_ace
*
*/
public interface SellCloth {
int sellCloth();
}


/**
* 在实体类中我们也同样实现SellCloth的接口,并且返回50块一件
* @author sky_ace
*
*/
public class ConcretSellCloth implements SellCloth {

@Override
public int sellCloth() {
return 50;
}

}


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
* 在代理类中我们这里要实现的是InvocationHandler来实现动态代理的功能,Invoke要传的
* 三个参数分别是proxy:指代理对象,这里是指targetObject
*          method:是指代理对象所要调用的接口中的方法,这里就是sellCloth
*          args:这里指所要传的参数列表
* return的值是在原有的50元一件的基础上加了150,所以返回结果应该是200
* @author sky_ace
*
*/
public class ProxySellCloth implements InvocationHandler {

public Object targetObject;

public void setTargetObject(Object tarObject)
{
this.targetObject = tarObject;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return (Integer)method.invoke(targetObject, args) + 150;
}

}


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
* 最后给出测试类,其中Proxy.newProxyInstance的三个参数的意义是:
* 第一个是被代理的对象的类加载器,这里指的是SellCloth的实例。
* 第二个是代理类所要实现的接口列表,这里用sellCloth.getClass().getInterfaces()的方法得到。
* 第三个是一个InvocationHandler类型的对象,表示在动态代理对象调用方法时会关联到哪个InvocationHandler类型的对象,这里指handler。
* @author sky_ace
*
*/
public class TestProxy {
public static void main(String[] args){
SellCloth sellCloth = new ConcretSellCloth();

ProxySellCloth proxySellCloth = new ProxySellCloth();

proxySellCloth.setTargetObject(sellCloth);

InvocationHandler handler = proxySellCloth;

Object proxy = Proxy.newProxyInstance(sellCloth.getClass().getClassLoader(), sellCloth.getClass().getInterfaces(), handler);

System.out.println(((SellCloth)proxy).sellCloth());

}
}


最后的输出结果也正是200,有人可能会有疑问,动态代理这么复杂,那什么情况会用到呢?这里我来简要的说一下,就是如果在比如struts,Spring等一些框架中就会经常的用到动态代理,因为框架只有在运行的时候利用反射知道类的信息,使用动态代理就可以在你的代码上加入一些框架所需要的信息而不影响你代码的完整性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 动态代理