论JDK动态代理的重要性及自定义自己的动态代理

汇川PLC和PLC之间ModebusTCP通讯 然后在全局变量中创建相应的变量关联IW和QW的寄存器创建全部变量//AM402作为主站——读H3U(D12-D21)//AM402作为主站——写给H3U(D200-D209)或者使用数组的方式。 阅读详情

1、JDK的动态代理

动态代理中的几个角色:

1、被代理类

在jdk中被代理类必须实现接口

2、代理类

在jdk中代理类是运行时动态生成的,所以你在工程中看不到代理类

3、通知类也叫advice

在jdk中通知类必须实现invocationHandler接口

 

在这里我们举个例子帮助理解

比如,张三是一个IT狗,到了适婚年龄但是没有对象,平时工作忙又没有时间找对象,这时候张三的父母就着急了张罗着给张三介绍对象,这时候张三的父母就拿着张三的照片、身份证等等可以代表张三的资料去媒婆那。这个就是最典型的代理,张三的父母代张三找对象,而不是张三本人,其实张三本人就只需要结婚就行了。找对象和照顾孩子的事情就有张三的父母代理了。

 

从这个例子中,我们提取出几个点:

1、张三,肯定是被代理对象,他要做的一件事情就是结婚。这里我们抽象下,张三是一个人,所以他需要实现people接口

2、张三的父母,张三的父母是具体的执行者,比如,代理张三找对象,张三结婚后帮忙张三照顾孩子,所以我们这里抽象出一个parent类,parent中有一个before方法,一个after方法。parent需要实现invocationHandler接口,它是一个通知类,负责具体执行

3、代理类,这是动态代理的难点,因为它是看不到摸不着的,它是存在在内存中的,且听博主慢慢道来。

OK~~~看代码吧。

people接口:

public interface People {
    public void zhaoduixiang() throws Throwable;
}

 

张三类:

public class ZhangSan implements People {
    
    /* 
     * 张三这个人,平时加班很忙,
     * 他有生理问题,要解放双手
     * 只关心有没有一个帮他解放双手这个人
     * 至于怎么去找,他不关心
     */
    @Override
    public void zhaoduixiang() {
        System.out.println("=============================找到对象,解放双手(你们懂的),然后结婚=====================");
    }
    
}

 

parent类:

/** 
 * @Description TODO 
 * @ClassName   Parent 
 * @Date        2018年9月26日 下午8:12:35 
 * @Author      zg-jack
 * 
 * 这个就是张三的父母类
 * 这个类的目的就是为了增强张三的zhaoduixiang()方法
 * 
 * 
 * 张三的父母需要持有张三这个人的引用
 * 
 * 
 */

public class Parent implements InvocationHandler {
    
    private People people;
    
    public Parent(People people) {
        this.people = people;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //前置增强
        before();
        
        //2、调用张三的这个人的zhaoduixiang方法
        method.invoke(people, args);
        
        //3、调用after()
        after();
        return null;
    }
    
    /** 
     * @Description TODO 
     * @param  参数 
     * @return void 返回类型  
     * @throws 
     * 
     * 在张三找到对象之前,帮助张三找对象
     */
    
    public void before() {
        System.out.println("&&&&&&&&&&&&&&&张三的父母,帮助张三找对象&&&&&&&&&&&&&&&&");
    }
    
    /** 
     * @Description TODO 
     * @param  参数 
     * @return void 返回类型  
     * @throws 
     * 
     * 找到对象要以后,张三父母帮他操持结婚
     */
    
    public void after() {
        System.out.println("&&&&&&&&&&&&&&&张三的父母,帮助张三操持结婚的事情&&&&&&&&&&&&&&&&");
    }
    
}

测试类:

public class MyTest {
    
    public static void main(String[] args) throws Throwable {
        //这个返回的对象就是张三这个人的代理对象
        People proxyPeople = (People)Proxy.newProxyInstance(MyTest.class.getClassLoader(),
                new Class<?>[] {People.class},
                new Parent(new ZhangSan()));
        createProxyClassFile();
        
        proxyPeople.zhaoduixiang();
    }
    
    /** 
     * @Description TODO 
     * @param  参数 
     * @return void 返回类型  
     * @throws 
     * 
     * 用流的方式把内存中的代理对象的字节码输出到.class文件中
     */
    
    public static void createProxyClassFile() {
        byte[] data = ProxyGenerator.generateProxyClass("$Proxy0",
                new Class[] {People.class});
        
        try {
            FileOutputStream out = new FileOutputStream("$Proxy0.class");
            out.write(data);
            out.close();
        }
        catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}

测试结果:

&&&&&&&&&&&&&&&张三的父母,帮助张三找对象&&&&&&&&&&&&&&&&
=============================找到对象,解放双手(你们懂的),然后结婚=====================
&&&&&&&&&&&&&&&张三的父母,帮助张三操持结婚的事情&&&&&&&&&&&&&&&&

从这个测试结果,我们仅仅用了一行调用代码

proxyPeople.zhaoduixiang();就出现了这个结果,而这个结果明显又是parent类中的invoke方法的打印结果,那么这里问题来了,谁调用了parent中的invoke方法???OK,带着这个问题,我们看一下图,从图中了解动态代理的调用过程,回答前面的代理类问题,如图:

从图中我们可以看出,proxypeople.zhaoduixiang()调用的实际上是内存中的代理对象,这个对象是程序在运行时的时候动态加载到内存里的,所以程序员看不到,那么有什么办法可以看到这个内存中的代理对象的代码呢,有办法~~~这个博主待会儿讲。从图中我们可以看出,带代理对象中,有一个属性,invocationHandler h属性,而h属性的值就是parent对象,而在代理对象中的方法zhaoduixiang中就只有一行代理,h.invoke(.......),其实就是掉到了parent对象中的invoke方法。。。这里就回答了刚刚那个问题,谁调了parent对象的invoke方法? 这下我们知道了,是内存中的代理对象调到了invoke方法。。。

那么还是回到前面的问题,内存中的代理对象,我们能拿到吗??OK,贴代码

/** 
     * @Description TODO 
     * @param  参数 
     * @return void 返回类型  
     * @throws 
     * 
     * 用流的方式把内存中的代理对象的字节码输出到.class文件中
     */
    
    public static void createProxyClassFile() {
        byte[] data = ProxyGenerator.generateProxyClass("$Proxy0",
                new Class[] {People.class});
        
        try {
            FileOutputStream out = new FileOutputStream("$Proxy0.class");
            out.write(data);
            out.close();
        }
        catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    

我们可以拿到字节码,然后用流的方式输出到.class文件中,然后用反编译工具反编译一下就可以了。。

 

为了让大家彻底领悟动态代理技术,我打算自己定义一个动态代理,不用jdk的proxy类和invocationHandler接口,这样才能彻底领悟

贴代码吧:

自定义的JackInvocationHandler接口,类似于JDK中的InvocationHandler接口

public interface JackInvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable;
}

最关键的是获取代理对象,因为这个代理对象在内存里面,在JDK中我们用Proxy这个类获取代理对象

People proxyPeople = (People)Proxy.newProxyInstance(MyTest.class.getClassLoader(),
                new Class<?>[] {People.class},
                new Parent(new ZhangSan()));

那么我们自己定义的动态代理里面,这个代理对象是如何获取呢??

MyParent类,类似于parent类

public class MyParent implements JackInvocationHandler {
    
    private People people;
    
    public MyParent(People people) {
        this.people = people;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //前置增强
        before();
        
        //2、调用张三的这个人的zhaoduixiang方法
        method.invoke(people, args);
        
        //3、调用after()
        after();
        return null;
    }
    
    /** 
     * @Description TODO 
     * @param  参数 
     * @return void 返回类型  
     * @throws 
     * 
     * 在张三找到对象之前,帮助张三找对象
     */
    
    public void before() {
        System.out.println("&&&&&&&&&&&&&&&张三的父母,帮助张三找对象&&&&&&&&&&&&&&&&");
    }
    
    /** 
     * @Description TODO 
     * @param  参数 
     * @return void 返回类型  
     * @throws 
     * 
     * 找到对象要以后,张三父母帮他操持结婚
     */
    
    public void after() {
        System.out.println("&&&&&&&&&&&&&&&张三的父母,帮助张三操持结婚的事情&&&&&&&&&&&&&&&&");
    }
    
}

MyProxy类,这个是最关键的核心代码,其功能类似于JDK中的Proxy类

public class MyProxy {
    
    private static String rt = "\r\n";
    
    /** 
     * @Description TODO 
     * @param @param loader
     * @param @param interfaces
     * @param @param h
     * @param @return 参数 
     * @return Object 返回类型  
     * @throws
     * 
     *  这个方法最终是需要返回一个代理对象
     *  1、运行时动态生成
     *  2、它是一个类
     *  3、它要实现people接口
     *  4、是以字节码的方式加载到内存中
     *    
     */
    public static Object newProxyInstance(ClassLoader loader,
            Class<?>[] interfaces, JackInvocationHandler h) {
        
        String fileName = "F:/workspace/proxy/src/main/java/com/zhuguang/jack/myproxy/$Proxy0.java";
        
        //1、我们要生成一个类,以字符串拼凑的方式,拼凑出一个类
        String javaClassStr = getJavaStr(interfaces);
        
        //2、通过流的方式生成java文件
        createJavaFile(javaClassStr, fileName);
        
        //3、动态编译java文件,生成.class文件
        compilerJava(fileName);
        
        //4、要把磁盘里面的.class文件内容加载到jvm的内存
        Object instance = LoadClass(h);
        return instance;
    }
    
    /** 
     * @Description TODO 
     * @param @param h
     * @param @return 参数 
     * @return Object 返回类型  
     * @throws 
     * 
     * 自定义一个类加载器
     */
    
    private static Object LoadClass(JackInvocationHandler h) {
        JackClassLoader jackClassLoader = new JackClassLoader(
                "F:/workspace/proxy/src/main/java/com/zhuguang/jack/myproxy");
        try {
            //返回的是一个被代理对象的Class对象
            Class<?> findClass = jackClassLoader.findClass("$Proxy0");
            Constructor<?> constructor = findClass.getConstructor(JackInvocationHandler.class);
            Object newInstance = constructor.newInstance(h);
            return newInstance;
        }
        catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    
    private static void compilerJava(String fileName) {
        JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
        
        StandardJavaFileManager standardFileManager = systemJavaCompiler.getStandardFileManager(null,
                null,
                null);
        
        Iterable<? extends JavaFileObject> javaFileObjects = standardFileManager.getJavaFileObjects(fileName);
        
        CompilationTask task = systemJavaCompiler.getTask(null,
                standardFileManager,
                null,
                null,
                null,
                javaFileObjects);
        task.call();
        try {
            standardFileManager.close();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    private static void createJavaFile(String javaClassStr, String fileName) {
        
        try {
            File f = new File(fileName);
            FileWriter fw;
            fw = new FileWriter(f);
            fw.write(javaClassStr);
            fw.flush();
            fw.close();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    
    private static String getJavaStr(Class<?>[] interfaces) {
        
        Method[] methods = interfaces[0].getMethods();
        
        String proxyClassStr = "package com.zhuguang.jack.myproxy;" + rt
                + "import java.lang.reflect.Method;" + rt
                + "public class $Proxy0 implements " + interfaces[0].getName()
                + "{" + rt + "JackInvocationHandler h;" + rt
                + "public $Proxy0(JackInvocationHandler h) {" + rt
                + "this.h=h;" + rt + "}"
                + getMethodString(methods, interfaces[0]) + rt + "}";
        
        return proxyClassStr;
    }
    
    private static String getMethodString(Method[] methods, Class intf) {
        
        String proxyMe = "";
        
        for (Method method : methods) {
            proxyMe += "public void " + method.getName()
                    + "() throws Throwable {" + rt + "Method md = "
                    + intf.getName() + ".class.getMethod(\"" + method.getName()
                    + "\",new Class[]{});" + rt
                    + "this.h.invoke(this,md,null);" + rt + "}" + rt;
            
        }
        
        return proxyMe;
    }
}

在这个类中有几个步骤:

1、生成代理类,我们用字符串拼凑的方式把类中的内容拼凑成String类型

2、通过流的方式把String写到java文件中

3、动态编译java文件,把它编译成.class文件

4、把磁盘中的.class文件加载到内存中并返回代理类的对象

通过这几个步骤,我们就可以拿到内存中的代理类,如此一个自己定义的动态代理就搞定了,是不是没有那么难?

 

希望博主的整理能够帮助到大家,如果大家觉得OK的话,麻烦点个赞,或者写个评论什么的,好歹我也要士气来 继续坚持我的原创博客之路啊,哈哈~~~~~

PHPStorm携手ThinkPHP8:开启高效开发之旅 本文围绕使用 PHPStorm 进行 ThinkPHP8 开发展开,先介绍开发环境搭建与 Xdebug 配置,再阐述 PHPStorm 集成 ThinkPHP8 的步骤,包括项目导入、解释器和服务器配置。还讲解了项目开发基础、数据库操作、高级技巧、调试处理及部署上线等内容,为开发者提供了从环境搭建到项目上线的完整指引,助力高效开展 ThinkPHP8 开发工作。 阅读详情

相关推荐

Containerd容器运行时的私有仓库镜像推送push和镜像拉取问题解决

向/etc/containerd/config.toml配置添加如下配置,然后重启containerd。向/etc/containerd/config.toml配置添加如下配置,然后重启containerd。通过crictl为k8s拉取镜像如下所示。可以通过ctr命令进行镜像推送。往私有仓库推送镜像如下。

Bulut0907 1万+

JAVA动态代理

java中有两种常见的动态代理方式 JDK原生动态代理和CGLIB动态代理使用以及原理

qq_32117059的博客 1785

【02】【VisionMaster V4.0.0 】安装教程—— 授权文件更新报错:应用程序与本地LM通讯出错(怀疑电脑加密 和 上网受限 造成的 )

本文详细介绍了海康VisionMaster 4.0试用版的安装流程及常见问题解决方案。主要内容包括:1)从官网下载基础安装包、试用补丁和授权文件;2)按顺序安装主程序、补丁和授权文件;3)针对授权失败问题提供两种解决方案(更换未加密电脑或使用加密狗);4)说明试用版的功能限制(30天试用期、2个流程限制等)。文章特别指出电脑加密可能导致授权失败,并提供了安装报错时的处理建议,为初次使用者提供了完整的安装指导。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 7176

【Spring篇】JDK动态代理

代理类的作用居然是拦截作用,你敢相信?进来看不一样的jdk动态代理,让你从根本上理解动态代理

m0_64231944的博客 3349

CAPL实战:从零构建HEX文件解析器,赋能UDS刷写

本文详细介绍了如何使用CAPL从零构建HEX文件解析器,以支持UDS刷写操作。通过解析HEX文件格式、设计状态机、优化数据结构与算法,实现高效准确的固件数据处理,并提供了与UDS刷写流程对接的工程化实践建议。

weixin_28726391的博客 444

从入门到精通:Cursor使用全攻略

Cursor是一款基于VSCode深度定制的AI编程工具,由Anysphere公司开发。它将AI技术与代码开发深度融合,能够理解自然语言指令并生成高质量代码,支持代码补全、跨文件上下文理解等功能。本文详细介绍了Cursor的安装设置、界面导航、基本操作和Composer模式等核心功能,并提供了高效提示词写作技巧和实际应用案例(如浏览器插件开发、复杂表单组件构建等)。文章还总结了使用注意事项和常见问题解决方案,展望了AI编程工具的发展前景。Cursor通过智能代码生成和项目理解能力,显著提升了开发效率,适合各

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 6460

JDK动态代理

代理模式【proxy】是对象的结构模式,代理模式给某一个对象提供一个代理对象,并由代理对象控制对象的引用。代理就是⼀个⼈或者⼀个机构代表另⼀个⼈或者另⼀个机构采取⾏动。在⼀些情况 下,⼀个客户不想或者不能够直接引⽤⼀个对象,⽽代理对象可以在客户端和⽬标对象之间 起到中介作⽤。代理模式的主要⽬标是:保护(隔离)和增强⽬标对象。

qq_59308271的博客 999

损失函数大汇总(六十一)(Signed Distance Map Loss附公式推导与代码)

摘要 本文介绍了Signed Distance Map (SDM) Loss,一种将形状先验直接融入分割任务的方法。SDM将每个像素表示为到目标边界的带符号距离(内部为负,外部为正),相比二值mask能更连续地表达形状几何信息。SDM Loss的核心思想是让网络学习这个隐式形状场,通过可微的Heaviside函数近似将SDM转换为分割结果。文中重点分析了一种product-based regression loss,它能同时关注距离数值和内外符号的正确性,对边界区域尤为敏感。SDM Loss通常与传统的分割

悦学共鸣,温柔以待,汇聚光芒,共同成长 189

温故知新之:代理模式,静态代理和动态代理(JDK动态代理)

代理模式,静态代理和动态代理(JDK动态代理)

小安安 620

整车电检工艺流程

本文是笔者在从事汽车行业智能制造领域过程,对于整车电检工艺流程的理解与总结。

qq_40664711的博客 1万+

34、Text2KGBench与GeoQuestions1089:知识图谱生成与地理空间问答的新进展

本文介绍了Text2KGBench和GeoQuestions1089在知识图谱生成与地理空间问答领域的最新进展。Text2KGBench提供了一个开放且可复现的基准,用于从文本生成知识图谱,并结合多个LLM模型和评估工具推动研究。GeoQuestions1089是目前最大的地理空间问答数据集,与GeoQA2系统结合,推动了地理空间问答系统的发展。文章还探讨了技术挑战和未来研究方向,包括多模态知识图谱生成和深度学习优化的地理空间问答系统。

css33的专栏 114

08.jdk动态代理原理

代理模式主要对我们方法执行之前与之后实现增强。

陌陌龙的博客 282

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

从头捋了一遍 JDK动态代理,收获颇丰!

看完美团、字节、腾讯这三家的一二三面试问题,是不是感觉问的特别多,可能咱们真的又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。开篇有提及我可是足足背下了Java互联网工程师面试1000题,多少还是有点用的呢,换汤不换药,不管面试官怎么问你,抓住本质即可!能读到此处的都是真爱Java互联网工程师面试1000题。

2401_84048586的博客 1129

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

从源码分析JDK动态代理

引言 动态代理非常的重要,虽然我们在日常的工作中没有非常底层的 编写过动态代理的代码,但是动态代理却起着非常重要的功能,想一下我们经常使用的框架: 日志框架、AOP等等,所以,如果我们需要看一些框架的源码的时候,还是需要非常熟悉的掌握动态代理的原理。 基本的使用这里就不在介绍了,前面的的博客已经介绍过了《java动态代理》,本篇博客主要解决下面几个问题: 1、JDK动态代理基本原理 2、如何调用到我们自己的myInvoerCationHandler中的invoke方法 3、 被代理的类位为什么要实

Jack 架构师之路 1426

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Spring—AOP三种实现方式(JDK动态代理与CGLIB动态代理)

JDK动态代理 JDK 动态代理只提供接口的代理,不支持类的代理。 核心InvocationHandler 接口和 Proxy 类,InvocationHandler 通过 invoke()方法 反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起; 接着,Proxy利用 InvocationHandler 动态创建一个符合某一接口的的实例, 生成目标类的代理对象。 CGLIB动态代理 如果代理类没有实现 InvocationHandler 接口,那么 Spring A..

Starry Sea 579

从头捋了一遍 JDK 动态代理,此次之后,永生难忘!

切莫死记硬背,小心面试官直接让你出门右拐1000道互联网Java面试题:

2401_84048521的博客 822

动态代理及注解

动态代理及注解.pdf.jztagtree{max-height:85vh;right:0px}.jzDown{top:10vh}.jztagtree li a{background-color:#b2c4d1}.jztagtree li a:before{border-right:10px solid #b2c4d1}.jztagtree li a:hover{...

行云的博客 152

连接池(自定义连接池、C3P0、Druit),代理模式(动态代理、静态代理、CGLIB动态代理)

一、线程池 为什需要线程池: 如果大雄每次需要使用法宝,多啦A梦都要去22世纪带过来,就会显得很麻烦,降低效率,浪费时间。所以多啦A梦需要百宝袋。 (获取数据库连接需要消耗比较多的资源,而每次操作都要重新获取新的连接对象,执行一次操作就把连接关闭,而数据库创建连接通常需要消耗相对较多的资源,创建时间也较长。这样数据库连接对象的使用率低。) 线程池是什么,有什么...

夜一 1395

RPC深入解析(上)

1.1 序列化技术 序列化的作用 在网络传输中,数据必须采用二进制形式, 所以在 RPC 调用过程中, 需要采用序列化技术,对入参对象和返回值对象进行序列化与反序列化。 如何进行序列化 自定义的二进制协议来实现序列化: 一个对象是如何进行序列化? 下面以 User 对象例举讲解: User 对象: package com.itcast; public class User { ​ /** * 用户编号 */ private String userNo = "0001"; ​

qianxingx的博客 708

Mybatis接口Mapper内的方法为啥不能重载?

这个月马上就又要过去了,还在找工作的小伙伴要做好准备了,小编整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!这个月马上就又要过去了,还在找工作的小伙伴要做好准备了,小编整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家[外链图片转存中…(img-ip4VQf0V-1712174578792)]

2301_79058522的博客 778

Spring学习记录 Day2(Spring进阶)

Day 1 2019年7月27日。 这是我学习Spring的第二天。 这一天,我学到了以下的知识。 代理 为什么要学习代理模式? 因为AOP(面向切面编程)的底层机制就是动态代理 代理模式的详解,可参考作者的另外一篇博客: https://blog.youkuaiyun.com/qq_41151659/article/details/97486756 代理 静态代理 动态代理 代理模式的角色分析 抽象角...

赈川 274

支付宝二面:Mybatis接口Mapper内的方法为啥不能重载吗?我直接懵逼了---

首先定义一个pojo。再定义一个接口UserMapper.java。接下来我们看看如何使用动态代理之投鞭断流,实现实例化接口并调用接口方法返回数据的。自定义一个InvocationHandler。@Overridetry {// 诸如hashCode()、toString()、equals()等方法,将target指向当前对象this// 投鞭断流。

2401_84440351的博客 750

Springboot中的缓存Cache和CacheManager原理介绍

一、背景理解 什么是缓存,为什么要用缓存? 程序运行中,在内存保持一定时间不变的数据就是缓存。简单到写一个Map,里面放着一些key,value数据,就已经是个缓存了。所以缓存并不是什么高大上的技术,只是个概念,把要多次使用的东西存在一个变量里,时不时取出来使用,就达到了缓存的目的,缓存就是存放数据的容器。那为什么要用缓存呢,是因为要多次使用。一个程序总有一些数据是可预见被多次使用(预见的准不准就是常说的命中率)比如一个复杂的计算结果,一次数据库访问取得的数据等耗时耗资源的数据就能放入缓存,目的就是为了

cristianoxm的博客 1万+

Spring完整版(四)

Spring完整版(四)十、代理模式10.1、静态代理10.2、静态代理再理解10.3、动态代理深化理解动态代理的好处十一、AOP11.1、什么是AOP11.2、Aop在Spring中的作用11.3、使用Spring实现Aop第一种方式第二种方式第三种方式 十、代理模式 为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 学习aop之前 , 我们要先了解一下代理模式! 10.1、静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象类来实现

Roc的博客 334

咋滴,不就是面试总考Spring的AOP吗,办它!

作者:小傅哥 博客:https://bugstack.cn 沉淀、分享、成长,让自己和他人都能有所收获!???? 一、前言幻珊小说网 https://www.tuou.info 为什么,你的代码总是糊到猪圈上? ????怎么办,知道你在互联网,不知道你在哪个大厂。知道你在加班,不知道你在和哪个产品争辩。知道你在偷懒,不知道你要摸鱼到几点。知道你在搬砖,不知道你在盖哪个猪圈。 当你特别辛苦夜以继日的完成着,每天、每周、每月重复性的工作时,你能获得的成长是最小,得到的回报也是少的。留着最多的汗、拿着最少的钱

weixin_57699483的博客 135

mybatis-plugin插件执行原理

今天主要是在看mybatis的主流程源码,其中比较感兴趣的是mybatis的plugin功能,这里主要记录下mybatis-plugin的插件功能原理。方法新建的代理对象中使用的InvocationHandler对象是Plugin本身,所以在执行方法的时候首先要调用它的。注解上的type、method、args属性去匹配,如果找到符合的,就会为对象创建代理对象,并返回代理对象。类似AOP,使用JDK动态代理,只不过mybatis的增强对象不是所有对象,而是上面陈列的4个对象而已。

weixin_47367099的博客 471
上一篇: 基于zookeeper的分布式队列之FIFO队列
下一篇: 分布式事务那些事儿之TCC
Jack爱258
博客等级 码龄10年 1288粉丝 124原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值