Java 动态代理类的实现

1、动态代理:为目标对象创建一个代理类,该代理类拥有目标对象的方法,属性,同时也可添加自己的方法,比如:日志的添加、校验等。

2、实现条件:在java中规定,要想产生一个对象的代理对象,那么这个对象必须要有一个接口,所以我们第一步就是设计这个对象的接口,在接口中定义这个对象所具有的行为(方法)

2、应用场景:当用户要调用一个类的方法时,用户可以通过调用代理,代理通过接口调用原来的类的方法,代理在把方法给用户前可以添加一些方法,如错误日志,用户类的方法运行的时间来监听类方法的性能。当代理完成时候就是当代理调用方法时候,就会启动InvocationHandler里的invoke方法(在测试类中代理类调用方法时有所体现)

3、实例关键点:java在JDK1.5之后提供了一个"java.lang.reflect.Proxy"类,通过"Proxy"类提供的一个newProxyInstance方法用来创建一个对象的代理对象,如下所示:

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

newProxyInstance方法用来返回一个代理对象,这个方法总共有3个参数,
ClassLoader loader用来指明生成代理对象使用哪个类装载器,
Class<?>[] interfaces用来指明生成哪个对象的代理对象,通过接口指定,
InvocationHandler h用来指明产生的这个代理对象要做什么事情。
所以我们只需要调用newProxyInstance方法就可以得到某一个对象的代理对象了。

4、实例如下:
1、目标对象接口:
public interface People {

/**
* 唱歌
* @param name
* @return
*/
public String sing(String name);

/**
* 跳舞
* @param name
* @return
*/
public String dance(String name);

}
2、实现接口的目标对象

/**
* 目标类对象
*/
public class LiuDeHua implements People{

@Override
public String sing(String name) {

return "唱"+name+"歌!好听!";
}

@Override
public String dance(String name) {
return "跳"+name+"舞!好看!";
    }
}
3、代理类的实现
/**
* 目标类(LiuDeHua)代理类
*/
public class LiuDeHuaProxy {
//类变量,代理类要代理的目标对象
private People ldh = new LiuDeHua();

public People getProxy() {
return (People) Proxy.newProxyInstance(LiuDeHuaProxy.class
.getClassLoader(), ldh.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
//此处可添加目标对象以外的方法。。。

//如果调用的是代理对象的sing方法
if (method.getName().equals("sing")) {

return method.invoke(ldh, args); //代理对象调用真实目标对象的sing方法去处理用户请求
}
//如果调用的是代理对象的dance方法
if (method.getName().equals("dance")) {

return method.invoke(ldh, args);//代理对象调用真实目标对象的dance方法去处理用户请求
}

return null;
}
});
}

}
4、测试动态代理类调用过程
public class Test {
public static void main(String[] args) {
//代理类
LiuDeHuaProxy proxy = new LiuDeHuaProxy();

//获得代理对象
People p = proxy.getProxy();

//调用代理对象的sing方法
String retValue = p.sing("冰雨");
System.out.println(retValue);

//调用代理对象的dance方法
String value = p.dance("江南style");
System.out.println(value);
}

}
5、博文学习借鉴:https://www.cnblogs.com/xdp-gacl/p/3971367.html

posted @ 2019-08-08 15:31  徐诺枫  阅读(1889)  评论(0编辑  收藏  举报