对象如果觉得自己干的事太多,可以通过代理转移一部分职责
对象有什么方法想被代理,代理就一定要有对应的方法
Java通过接口(接口中提供被代理对象的抽象功能,由代理实现即可)来保证代理的样子
java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interface,InvocationHandler h)
参数一:loader:类加载器,作用是加载代理类
参数二:interfaces:代理接口包含的内容,为数组形式
参数三:h:传递InvocationHandler的实现类对象,用来指定代理对象的具体功能
通过invokehandler的invoke方法指定代理干的事,这个invoke会被代理的方法在底层回调,参数需要接收(被代理的对象,invoke调用者所需要的参数(数组形式)
定义Star接口(保证代理的样子):提供抽象方法,表示需要代理的方法
public interface Star {
/**
* @param songName 歌名
* @return 唱完歌的反馈
*/
public abstract String sing(String songName);
/**
* 跳舞,无参无返
*/
public abstract void dance();
}
定义BigStar类:实现Star接口,重写Star中的抽象方法
提供成员变量name,提供sing和dance方法
public class BigStar implements Star {
private String name;
public BigStar(String name) {
this.name = name;
}
@Override
public String sing(String songName) {
System.out.println(name + "正在唱:" + songName);
return "谢谢大家~"; //唱完歌的反馈
}
@Override
public void dance() {
System.out.println(name + "正在优美的跳舞~");
}
}
定义ProxyUtil类:提供静态方法创建代理,接收被代理对象(BigStar),多态返回代理对象Star
(1)java提供的为对象创建代理的方法(三个参数)Proxy.newProxyInstance
(2)重写后的invoke方法:用来指定代理对象的具体功能(回调方法:被sing和dance在底层调用)
(3)返回代理对象
public class ProxyUtil {
public static Star createProxy(BigStar bigStar) {
//java提供的为对象创建代理的方法(三个参数)
Star starProxy = (Star) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(), //类加载器,作用是加载代理类
new Class[]{Star.class}, //代理接口包含的内容,为数组形式
new InvocationHandler() { //InvocationHandler的实现类对象,用来指定代理对象的具体功能
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//Object proxy:代理对象
//Method method:invoke的调用者,可能是sing方法,也可能是dance方法
//Object[] args:invoke调用者所需要的参数(数组形式)
//判断当前invoke的调用者
if (method.getName().equals("sing")) {
//代理要做的事
System.out.println("准备话筒,收钱..");
}else if(method.getName().equals("dance")){
//代理要做的事
System.out.println("准备场地,收钱..");
}
//代理做了该做的,剩余都由本尊做
return method.invoke(bigStar, args);
}
}
);
//返回代理对象
return starProxy;
}
}
测试类:通过ProxyUtil类获取代理对象,调用被代理的方法(sing、dance)
public class Test {
public static void main(String[] args) {
Star starProxy = ProxyUtil.createProxy(new BigStar("周杰伦"));
String result = starProxy.sing("晴天");
System.out.println(result);
System.out.println("--------------");
starProxy.dance();
}
}