欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于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 方法 反射执行方法 三个参数 执行该方法的对象 方法 参数。