关于java动态代理的一些个人理解
程序员文章站
2024-02-09 18:14:16
...
首先设想一个场景 有一项活动 需要请一位歌手来表演 ,我们要直接去联系歌手吗? 答案肯定是 错的 我们应该要去联系歌手的经纪人 和经纪人去商量歌手的出场费用和出场时间等事项 而歌手只负责表演 经纪人和歌手的关系就属于代理和被代理的关系 经纪人可以让歌手去表演,同时扩展更多歌手不去做的事项(如收钱)
上代码:
Singer接口
public interface Singer { void dance(); String singing(String song); }
JingJiRen
public class JingJiRen implements Singer{
private Singer singer = new XuShan(); @Override public void dance() { System.out.println("给钱"); singer.dance(); }
@Override public String singing(String song) { System.out.println("给钱"); return singer.singing(song); } }
XuShan(徐山是一名歌手)
public class XuShan implements Singer{
@Override public void dance() { System.out.println("我爱跳舞"); }
@Override public String singing(String song) { System.out.println("我要唱歌"); return "我要表演的歌曲是"+song; } }
测试类
public class Main {
public static void main(String[] args) { JingJiRen jiRen = new JingJiRen(); jiRen.dance(); String song = jiRen.singing("aaa"); System.out.println(song); }
}
在JingJiRen类中 有XuShan类的 对象 说明 JingJiRen类可以让歌手XuShan 去表演 同时 JingJiRen 又在方法中进行了扩展 增加了收钱 这一项 ,我们在测试类中调用的 是JingJiRen 类的对象 但实际去做 唱歌跳舞的还是歌手XuShan。这就是代理和被代 理人的关系 ,而上述代码实现 在Java 称为 静态代理
然后讲动态代理
相比于静态代理 动态代理是反射配合上代理 创建代理类去执行反射回来的类的方法 好处是不需要代理人和被代理人 一对一绑定的模式 ,一个代理类就可以代理多个被代 理类。
上代码:
public class Test {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class<?> clazz = Class.forName("com.qcby.aop.XuShan"); //创建一个被代理人的实例 Object singer1 = clazz.newInstance(); // 创建一个代理人的实例 /** * 三个参数 * getClassLoader 传入类加载器 * getInterfaces 传入这个类所实现的所有接口 * 第三个参数是需要被代理的类 * */ Object o = Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),new ProxySinger(singer1)); if (o instanceof Singer) { Singer singer = (Singer) o; singer.dance(); String song = singer.singing("aaa"); System.out.println(song); singer.toString(); } }
private static class ProxySinger implements InvocationHandler { private Singer singer; public ProxySinger(Object p0) { this.singer = (Singer) p0; }
@Override
/*
* proxy 调用 invoke 的对象 method 当前执行的方法 args 参数
* */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("加钱");
Object invoke = method.invoke(singer,args);
return invoke;
}
} }
首先通过反射得到被代理类的信息 ,创建被代理类的实例(newInstance) ,再通过proxynewInstance 方法创建代理类的实例 Instanceof 方法用来判断 左边对象是否为右边类的实例,是做强制类型转换的前题 ProxySinger 类中 声明执行的一些扩展内容 和invoke 执行方法。 invoke 方法 反射执行方法 三个参数 执行该方法的对象 方法 参数。
上一篇: [读书笔记]高级字符驱动程序(第六章)
下一篇: 软件构造Lab4实验总结—日志