java动态代理原来so easy!

代理的概述

为什么要有“代理”?生活中就有很多例子,例如委托业务等等,代理就是被代理者没有能力或者不愿意去完成某件事情,需要找个人代替自己去完成这件事,这才是“代理”存在的原因。例如,我现在需要出国,但是我不愿意自己去办签证、预定机票和酒店(觉得麻烦 ,那么就可以找旅行社去帮我办,这时候旅行社就是代理,而我自己就是被代理了。

1.代理模式概述

1.1什么是代理模式

ProxyPattern(即:代理模式),23种常用的面向对象软件的设计模式之一
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

​ 作用:增强一个类中的某个方法.对程序进行扩展.

1.2动态代理介绍

​ 动态代理它可以直接给某一个目标(被代理 对象)对象(实现了某个或者某些接口)生成一个代理对象,而不需要代理类存在。

​ 动态代理与代理模式原理是一样的,只是它没有具体的代理类,直接通过反射生成了一个代理对象。

  • 动态代理的获取:

    ​ jdk提供一个Proxy类可以直接给实现接口类的对象直接生成代理对象

2.jdk中的动态代理的使用

2.1API介绍

Java.lang.reflect.Proxy类可以直接生成一个代理对象

  • Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)生成一个代理对象
    • 参数1:ClassLoader loader 被代理对象的类加载器 一
    • 参数2:Class<?>[] interfaces 被代理对象的要实现的接口
    • 参数3:InvocationHandler h (接口)执行处理类
    • 返回值: 代理对象
  • **InvocationHandler中的invoke(Object proxy, Method method, Object[] args)**方法:调用代理类的任何方法,此方法都会执行
    • 参数3.1:代理对象(慎用)
    • 参数3.2:当前执行的方法
    • 参数3.3:当前执行的方法运行时传递过来的参数
      • 返回值:当前方法执行的返回值
2.2代码实现
//抽象接口  被代理者和代理者要实现的抽象方法
public interface FindHappy{
    void happy();
}

//被代理人
public class JinLian implements FindHappy{

    public void happy(){
        System.out.println("金莲happy...");
    }
}


public class Demo {
    public static void main(String[] args) {
        /*
            动态代理:可以直接生成一个代理对象 ,不需要创建代理类
            Java.lang.reflect.Proxy类: 表示代理
            作用:Proxy类中提供了很多静态方法,可以动态的生成一个代理对象
            静态方法:
                static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 动态生成一个类的代理对象
                参数1loader: 表示被代理类的类加载器   被代理类的字节码对象.getClassLoader()
                参数2interfaces: 表示被代理类实现的所有接口的数组  被代理类的字节码对象.getInterfaces()
                以上这2个参数,就是为了动态生成一个代理对象

                参数3InvocationHandler: 执行处理接口,传入InvocationHandler实现类,用来执行代理对象要执行的方法
                参数3为了执行代理对象调用的方法
                InvocationHandler接口中的方法;
                        public Object invoke(Object proxy, Method method, Object[] args){}
                        1. 但凡是代理对象调用方法就会执行InvocationHandler中invoke方法
                        2. invoke方法中的参数1 proxy: 表示动态生成的代理对象,注意,在invoke方法里面不要使用proxy调用方法,否则会栈内存溢出错误
                        3. invoke方法中的参数2 method: 表示代理对象调用的方法
                        4. invoke方法中的参数3 args: 表示代理对象调用的方法 传入的实参
                        5. invoke方法中的返回值类型: 表示代理对象调用的方法的 返回值类型
         */
        JinLian jinLian = new JinLian();
        // 使用动态代理模式生成JinLian的代理对象:
        FindHappy proxy = (FindHappy) Proxy.newProxyInstance(JinLian.class.getClassLoader(), JinLian.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("王婆以做头发的名义把房间开好了...");
                method.invoke(jinLian);
                System.out.println("happy完后,王婆打扫战场...");
                return null;
            }
        });
        System.out.println("呵呵呵");
        proxy.happy();// 代理对象执行happy方法
        System.out.println("嘿嘿嘿");  
    }
}

  "D:\Program Files\Java\jdk1.8.0_291\bin\java.exe" -javaagent:D:\soft\ideaIC-2022.2.win\lib\idea_rt.jar=63164:D:\soft\ideaIC-2022.2.win\bin -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;E:\projects\sifang-master\demo\target\classes;D:\maven\repository\org\springframework\boot\spring-boot-starter\2.3.0.RELEASE\spring-boot-starter-2.3.0.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot\2.3.0.RELEASE\spring-boot-2.3.0.RELEASE.jar;D:\maven\repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-logging\2.3.0.RELEASE\spring-boot-starter-logging-2.3.0.RELEASE.jar;D:\maven\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\maven\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\maven\repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;D:\maven\repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.2\log4j-to-slf4j-2.13.2.jar;D:\maven\repository\org\apache\logging\log4j\log4j-api\2.13.2\log4j-api-2.13.2.jar;D:\maven\repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;D:\maven\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\maven\repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;D:\maven\repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-web\2.3.0.RELEASE\spring-boot-starter-web-2.3.0.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-json\2.3.0.RELEASE\spring-boot-starter-json-2.3.0.RELEASE.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-databind\2.11.0\jackson-databind-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-annotations\2.11.0\jackson-annotations-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-core\2.11.0\jackson-core-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.0\jackson-datatype-jdk8-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.0\jackson-datatype-jsr310-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.0\jackson-module-parameter-names-2.11.0.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-tomcat\2.3.0.RELEASE\spring-boot-starter-tomcat-2.3.0.RELEASE.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.35\tomcat-embed-core-9.0.35.jar;D:\maven\repository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.35\tomcat-embed-websocket-9.0.35.jar;D:\maven\repository\org\springframework\spring-web\5.2.6.RELEASE\spring-web-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-webmvc\5.2.6.RELEASE\spring-webmvc-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot-autoconfigure\2.3.0.RELEASE\spring-boot-autoconfigure-2.3.0.RELEASE.jar" com.sifang.Demo
呵呵呵
王婆以做头发的名义把房间开好了...
金莲happy...
happy完后,王婆打扫战场...
嘿嘿嘿

Process finished with exit code 0

图片不得转载

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘右今

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值