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

设计模式之JDK动态代理

2017-11-11 22:00 387 查看
设计模式是一套反复使用的、多数人知晓的、经过分类编目的、代码设计经验总结。使用设计模式为了提高代码的可重用性,让代码更容易被他人理解,保证代码的可靠性。

For example :比如某歌星知名度非常高,很多单位都想请他去唱歌,但是呢,总不能他又要唱歌又要给自己接活吧,一般的都会雇佣一个经济人,这里的经济人他就是一个代理。如果有人想请该歌星去唱歌,那么需要直接联系的人是歌星的经济人,而不是直接找歌星,找到该经纪人以后谈好价钱,然后歌星再来唱歌,唱完歌以后,可能还需要与经纪人之间进行一些后续事物的处理。

一、代理模式的定义

为其他对象提供一种代理以控制对这个对象的访问

代理对象起到中介作用,可去掉功能服务或增加额外的服务

二、JDK动态代理

Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:

(1) java.lang.reflect.InvocationHandler:该接口中仅定义了一个方法

public Object invoke(Object obj,Method method,Object[] args)

参数:

obj一般是指代理类;

method是被代理的方法;

args为该方法的参数数组。

这个抽象方法在代理类中动态实现。

(2)java.lang.reflect.Proxy:该类即为动态代理类

static Object newProxyInstance(ClassLoader loader,Class[] interfaces,

InvocationHandler h)

返回代理类的一个实例,返回后的代理类可以当做被代理类使用

(可使用被代理类的在接口中声明过的方法)

jdk动态代理的使用步骤:

1.创建一个实现InvocationHandler接口的类,它必须实现invoke方法

2.创建被代理的类以及接口

3.调用Proxy的静态方法,创建一个代理类

newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

4.通过代理调用方法

代码示例:

package com.tong.Proxy;
/**
* @describe 抽象接口
* @author tong
* @version 1.0 2017-11-11
*/
public interface Person {
public void sing();
}


package com.tong.Proxy;
/**
* @describe Person接口的具体实现 歌手Singer
* @author tong
* @version 1.0 2017-11-11
*/
public class  Singer implements Person {
@Override
public void sing() {
System.out.println("********************歌手:我正在唱歌***********************");
}
}


package com.tong.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
* @describe 使用JDK动态代理
* @author tong
* @version 1.0 2017-11-11
*/
public class AgencyHandler implements InvocationHandler {
private Object target;
public AgencyHandler(Object target) {
super();
this.target = target;
}
/**
* 参数:
* proxy 被代理对象
* method 被代理对象方法
* args 方法的参数
* 返回值:
* Object 方法的返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("******************演唱会以前:经纪人与合作商谈好价钱并签订合同***********************");
method.invoke(target);
System.out.println("******************演唱会以后:合作商按照合同把钱支付给经纪人***********************");
return null;
}

}


package com.tong.Proxy;

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

public class Test {
public static void main(String[] args){
Singer singer = new Singer();
Class cls = singer.getClass();
InvocationHandler h = new AgencyHandler(singer);
// 使用Proxy类newProxyInstance方法动态创建代理类
/**
* loader 类加载器
* interfaces 实现接口
* h InvocationHandler
*/
//输出生成的代理类的类名,默认类名一般是$Proxy0,$Proxy1、$Proxy2等等
System.out.println(Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h).getClass());

Person p = (Person) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
p.sing();

}

}


运行结果:

class com.sun.proxy.$Proxy0
******************演唱会以前:经纪人与合作商谈好价钱并签订合同***********************
********************歌手:我正在唱歌***********************
******************演唱会以后:合作商按照合同把钱支付给经纪人***********************
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: