特点:
动态代理可以无侵入式的给代码增加额外的功能
为什么需要代理:
对象如果嫌身上干的事情太多,可以通过代理来转移部分职责。
代理长什么样:
对象有什么方法想被代理,代理就一定要有对应的方法,方法内一般是先进行准备,在去找对象调用对应的方法。
Java通过什么来保证代理的样子:
通过接口保证,对象和代理需要实现同一个接口,接口中就是被代理的所有方法。
代码演示:
测试类:
public class Test {
public static void main(String[] args) {
BigStar kun = new BigStar("鲲哥");
Star proxy = ProxyUtil.createProxy(kun);
//调用唱歌方法
String result = proxy.sing("及你太美");
System.out.println(result);
System.out.println("=============");
//调用跳舞
proxy.dance();
}
}
JavaBean类BigStar:
public class BigStar implements Star{
private String name;
@Override
public String sing(String name) {
System.out.println(this.name + "正在唱" + name);
return "谢谢大家";
}
@Override
public void dance() {
System.out.println(this.name + "正在跳舞");
}
public BigStar() {
}
public BigStar(String name) {
this.name = name;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
public String toString() {
return "BigStar{name = " + name + "}";
}
}
代理工具包类ProxyUtil :
public class ProxyUtil {
public static Star createProxy(BigStar bigStar) {
Star star =(Star) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),//参数一:用于指定用哪个类加载器,去加载生成的代理
new Class[]{Star.class},//参数二:指定接口,这些接口用于指定生成的代理长什么样
//参数三:用来指定生成的代码对象要干什么事情
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//参数一:代理运行的对象
//参数二:要运行的方法
//参数三:调用方法时,传递的实参
if("sing".equals(method.getName())) {
System.out.println("代理在准备话筒,收钱");
} else if ("dance".equals(method.getName())) {
System.out.println("代理在收拾舞台,收钱");
}
return method.invoke(bigStar,args);
}
}
);
return star;
}
}
接口Star:
public interface Star {
public abstract String sing(String name);
public abstract void dance();
}