Java 动态代理类的实现
程序员文章站
2023-04-04 20:26:07
1、动态代理:为目标对象创建一个代理类,该代理类拥有目标对象的方法,属性,同时也可添加自己的方法,比如:日志的添加、校验等。 2、实现条件:在java中规定,要想产生一个对象的代理对象,那么这个对象必须要有一个接口,所以我们第一步就是设计这个对象的接口,在接口中定义这个对象所具有的行为(方法) 2、 ......
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
上一篇: INTERVAL 用法 mysql
下一篇: ES6——箭头函数与普通函数的区别