package proxy;
public class BigStar implements Star {
private String name;
public BigStar(String name) {
this.name = name;
}
@Override
//明星只负责演唱,至于准备工作和扫尾工作交给代理完成
public String sing(String singName) {
System.out.println(this.name + "正在演唱:" + singName);
return "演出结束,谢谢大家";
}
@Override
public void dance() {
System.out.println(this.name + "正在表演舞蹈...");
}
public String getName() {
return name;
}
}
1.Star接口
package proxy;
public class BigStar implements Star {
private String name;
public BigStar(String name) {
this.name = name;
}
@Override
//明星只负责演唱,至于准备工作和扫尾工作交给代理完成
public String sing(String singName) {
System.out.println(this.name + "正在演唱:" + singName);
return "演出结束,谢谢大家";
}
@Override
public void dance() {
System.out.println(this.name + "正在表演舞蹈...");
}
public String getName() {
return name;
}
}
明星类,实现Star接口。明星类只专注业务的实现,至于其他无关工作(如这里的准备和收尾工作)应该交给代理类完成。
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
//为哪个明星生成代理
//注意,由于外部找的都是代理对象,而代理对象才去调用BigStar底层的方法。
//因此,生成的代理对象应该和BigStar一样都有共同的方法sing和dance
//
public static Star createProxy(BigStar bigStar) {
//第一个参数:用于指定一个类加载器
//第二个参数:指定生成的代理对象应该有哪些方法,传入一个接口数组
//第三个参数:用来指定代理对象具体应该做什么事
Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
new Class[]{Star.class},
new InvocationHandler() {
//这个invoke方法是一个回调方法
//当Star starProxy = ProxyUtil.createProxy(s); 创建一个代理对象时
//starProxy.sing("好运来") starProxy.dance() 代理对象调用sing方法或者dance方法时,
//这两个方法就会回调invoke方法!
@Override
//第一个参数:表示被代理的对象,也就是这里的bigStar对象
//第二个参数:表示回调这个invoke的方法(sing、dance)
//第三个参数:表示回调invoke方法中的参数(比如说sing(String sing) 中的singName)
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object o = new Object();
if (method.getName().equals("sing")) {
System.out.println("正在准备唱歌的场地和话筒...");
//调用被代理对象的方法
o = method.invoke(bigStar, args);
System.out.println("演唱会结束,工作人员正在清理现场...");
} else if (method.getName().equals("dance")) {
System.out.println("正在准备舞台");
method.invoke(bigStar, args);
System.out.println(bigStar.getName() + "跳舞结束,工作人员正在清理现场...");
}
return o;
}
}
);
return star;
}
}
代理类,注意这里采用匿名内部类的形式重写invoke方法。
package proxy;
public class Test {
public static void main(String[] args) {
BigStar bigStar = new BigStar("周杰伦");
Star proxy = ProxyUtil.createProxy(bigStar);
System.out.println(proxy.sing("双截棍"));
proxy.dance();
}
}
测试类