首页IT科技java代理原理(对java中代理的理解笔记)

java代理原理(对java中代理的理解笔记)

时间2025-09-19 08:23:45分类IT科技浏览6204
导读:简单例子 package com.kfm.jdbc.day0328; import...

简单例子

package com.kfm.jdbc.day0328; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public interface Actor { void sing(double money); void jump(double money); } class Kun implements Actor{ @Override public void sing(double money) { System.out.println("收了" + money + "元                ,唱了一首《只因你太美》"); } @Override public void jump(double money) { System.out.println("收了" + money + "元                         ,跳了一个舞"); } } class Agent implements Actor{ private Actor actor; public Agent(Actor actor){ this.actor = actor; } @Override public void sing(double money) { this.actor.sing(money * 0.8); } @Override public void jump(double money) { this.actor.jump(money * 0.9); } } class Main { public static void main(String[] args) { Kun kun = new Kun(); Actor o = (Actor) Proxy.newProxyInstance(Kun.class.getClassLoader(), new Class[]{Actor.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String name = method.getName(); if ("sing".equals(name)){ System.out.println("请他唱歌先请我吃饭"); return method.invoke(kun, args); } else { System.out.println("做其他事得加钱"); return method.invoke(kun, args); } } } ); o.sing(1.1); o.jump(2.2); // Agent agent = new Agent(kun); // agent.sing(50000); } }

对例子进行分析:

有一个actor的接口         ,有jump和sing两个方法 ikun实现了此接口 但是你能直接见到IKUN吗??? 因此需要一个agent也来实现actor接口            ,但是                        ,agent需要赚一点差价 现在在代码每次运行时             ,来一个agent        ,因此就用到代理:

在 Main 类中                        ,首先创建了一个 Kun 对象 kun                 ,然后使用 Java 反射机制    ,创建了一个代理对象 o                        ,代理的是 Kun 类                 。在代理对象的创建过程中                     ,传入了 Kun 类的类加载器                 、Actor 接口的 Class 对象和一个 InvocationHandler 对象                         。这个 InvocationHandler 对象的作用是拦截代理对象方法的调用,对调用进行增强        。在 invoke 方法中                    ,首先判断调用的方法是 sing 还是 jump                         ,如果是 sing 方法    ,则输出一条信息“请他唱歌先请我吃饭                 ”                ,然后再调用 kun 对象的 sing 方法            。如果是 jump 方法                         ,则输出一条信息“做其他事得加钱                         ”         ,然后再调用 kun 对象的 jump 方法                         。最后            ,通过代理对象 o 调用了 sing 和 jump 方法            。在这个示例中                        ,代理对象 o 拦截了 sing 和 jump 方法的调用             ,对 sing 方法进行了增强        ,输出了一条信息                        ,而对 jump 方法没有进行增强                 ,只是输出了一条提示信息        。

Proxy.newProxyInstance 是 Java 动态代理的一个方法    ,用于创建代理对象                         。它有三个参数:

ClassLoader 类加载器                        ,用于加载代理对象的 Class 文件                。

Class [] interfaces                     ,被代理对象实现的接口列表,这些接口必须是非 final 类型    。

InvocationHandler invocationHandler                    ,实现了 InvocationHandler 接口的对象                         ,用于拦截代理对象的方法调用并进行增强                         。

在这段代码中    ,Kun.class.getClassLoader() 表示使用 Kun 类的类加载器来加载代理对象的 Class 文件                    。new Class[]{Actor.class} 表示要代理的接口列表                ,这里只有 Actor 接口。new InvocationHandler() 表示实现了 InvocationHandler 接口的对象                         ,这里使用了匿名内部类来实现                     。在这个匿名内部类中         ,重写了 invoke 方法            ,用于拦截代理对象的方法调用并进行增强                        。

最后                        ,将代理对象强制转换为 Actor 类型             ,并将其赋值给 o 变量        ,o 可以调用 Actor 接口中的方法                        ,实际上调用的是被代理对象 Kun 的对应方法                 ,而 InvocationHandler 中的增强操作也会被执行    。

invoke() 方法是 InvocationHandler 接口中的一个方法    ,用于拦截代理对象的方法调用并进行增强                 。它有三个参数:

Object proxy                        ,代理对象本身                     ,通常在 invoke() 方法中不会使用到                         。

Method method,代理对象被调用的方法对象        。

Object[] args                    ,代理对象被调用的方法的参数列表            。

在这段代码中                         ,invoke() 方法首先通过 Method 对象获取被调用方法的名字    ,然后判断被调用的方法是 sing 还是其他方法                         。如果是 sing 方法                ,就输出一句话并调用被代理对象 Kun 的 sing() 方法                         ,并将其返回值作为 invoke() 方法的返回值            。如果是其他方法         ,就输出另一句话并调用被代理对象 Kun 的对应方法            ,并将其返回值作为 invoke() 方法的返回值        。

因此                        ,当代理对象 o 调用 sing() 方法时             ,实际上会调用 invoke() 方法        ,并在其中输出一句话                        ,并调用被代理对象 Kun 的 sing() 方法                 ,并将其返回值作为 o.sing() 的返回值                         。当代理对象 o 调用 jump() 方法时    ,实际上也会调用 invoke() 方法                        ,并在其中输出另一句话                     ,并调用被代理对象 Kun 的 jump() 方法,并将其返回值作为 o.jump() 的返回值                。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
扩词法和组词法的区别(词库的扩充百度百科的抓取你知道这些热词吗? rabbit9898 ITeye技术网站)