动态代理
特点 : 无侵入式的给带代码增加额外的功能
如果对象的方法太多太复杂臃肿,可以将部分职责转交给代理,由代理先执行部分业务。
对象有那些方法需要被代理,代理就必须要有对应方法。
代理获取对象需要代理的方法:用接口的方式实现
将需要被代理的方法写入接口:
public interface method {
public abstract String sing(String name);
public abstract void dance(String name);
}
创建java对象并实现接口:
public class CaiXvKun implements method{
public CaiXvKun(){};
public String sing(String name){
System.out.println("正在演出歌曲" + name);
return "喜欢我就支持我吧(比心)";
}
public void dance(String name){
System.out.println("正在跳" + name);
}
}
接下来需要构建代理对象:
public class ProxyUtil {
//形参:被代理的对象
//返回值:代理
public static Agency creatProxy(CaiXvKun Kun) {
//为蔡徐坤(Kun)创建代理
//形参一:指明类加载器加载字节码文件到内存中 格式基本固定为:当前类.class.getClassLoader
//形参二:指明接口,指定生成的代理应含有那些方法 是数组形式,若还需指明其他接口可直接输入{}内
//形参三; 指定代理需要执行的业务
Agency agency = (Agency) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),
new Class[]{Agency.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//参数一: 代理的对象
//参数二: 代理的方法
//参数三: 代理的方法的参数
if (method.getName().equals("sing")) {
System.out.println("Music");
}else if( method.getName().equals("dance")) {
System.out.println("篮球+1");
}
//调用被代理对象的方法
return method.invoke(Kun, args);
}
}
);
return agency;
}
}
接下来开始实际获取代理对象执行业务;
public class Test {
public static void main(String[] args) {
//获取代理对象
CaiXvKun kunkun = new CaiXvKun();
Agency proxy = ProxyUtil.creatProxy(kunkun);
//调用方法
String result = proxy.sing("鸡你太美");
System.out.println(result);
}
}
流程
指明需代理对象类CaiXunKun后,我们通过在ProxyUtil类下creatProxy方法调用Proxy.newProxyInstance()方法构造代理并加载到内存中。main方法中实际调用时,获取完代理对象后,代理对象直接调用代理方法,实际也是调用到了invoke方法使得可以接着调用被代理对象的方法。实现了代理执行完业务接着执行被代理对象的业务并接收到返回值这一过程、