IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring动态代理的两种方式 -> 正文阅读

[Java知识库]Spring动态代理的两种方式

1. Spring创建的动态代理类在哪??

Spring 框架在运行时,通过字节码技术,在jvm创建的,运营在jvm内部,等程序结束后,会和jvm一起消失。

1.1 什么叫动态字节码技术?

通过第三方动态字节码框架,在jvm中创建对应类的字节码,进而创建对象,当虚拟机结束,动态字节码跟着消失。==
结论
动态代理不需要定义类文件,都是在jvm运行过程中创建的,所以不会造成静态代理,类文件数量过多,影响项目管理的问题。
第三方动态字节码框架:ASM,javassist ,cglib

2.JDK的动态代理

2.1 Proxy.newProxyInstance?法参数详解

Proxy.newProxyInstance(ClassLoader, Interfaces, handler);

参数1ClassLoader:借用一个类加载器,创建代理类,的class对象,进而可以创建代理对象。
参数2Interfaces:原始对象的接口,例如:

TestService testService = new TestServiceImpl();
//参数2Interfaces:testService.getClass().getInterfaces();

参数3:handler 即 invocationHandler
作用:用于书写额外功能,额外功能运行在原始方法之前 ,之后,抛出异常。
例如:

 InvocationHandler handler = new InvocationHandler() {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("------proxy  log  before --------");
        //原始方法运行
        Object ret = method.invoke(testService, args);
        System.out.println("------proxy  log  after --------");
        return ret;
    }
};

上述代码中各个参数的含义:
返回值:Object:原始方法的返回值。
参数:proxy: 可忽略,代表的是代理对象;
method:额外功能所增加给的那个原始方法,可调用invoke()方法执行原始方法
args[]:原始方法的参数

2.1 编码

前置条件:
一个接口和一个接口的实现类,例如:
接口:

public interface TestService {

    boolean login(String username, String passoword);
}

实现类:

public class TestServiceImpl implements TestService {
    @Override
    public boolean login(String username, String passoword) {
        System.out.println("username = " + username + "password = " + passoword);
        return true;
    }
}

开始编写动态代理:

public class TestProxy {
 public static void main(String[] args) {
     //1. 创建原始对象
     TestService testService = new TestServiceImpl();
     //2. 创建JDK动态代理
     InvocationHandler handler = new InvocationHandler() {
         @Override
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
             System.out.println("------proxy  log  before --------");
             //原始方法运行
             Object ret = method.invoke(testService, args);
             System.out.println("------proxy  log  after --------");
             return ret;
         }
     };

     /*
       ClassLoader loader,借用一个类加载器 创建代理类的class对象  ,进而可以创建代理对象
       Class<?>[] interfaces,
       InvocationHandler h
      */
     TestService testServiceProxy = (TestService) Proxy.newProxyInstance(TestServiceImpl.class.getClassLoader(), testService.getClass().getInterfaces(), handler);
     testServiceProxy.login("123", "123");
 }

运行结果:
在这里插入图片描述

3. CGlib的动态代理

CGlib创建动态代理的原理:??继承关系创建代理对象,原始类作为?类,代理类作为?类,这样既可以保证2者?法?致,同时在代理类中提供新的实现(额外功能+原始?法);

3.1 编码

前置条件跟上面一样

public class TestCglib {
    public static void main(String[] args) {
        // 1. 创建原始对象
        TestService testService = new TestService();
        //2 .通过cglib创建动态代理对象
        Enhancer enhancer = new Enhancer();
        enhancer.setClassLoader(testService.getClass().getClassLoader());
        enhancer.setSuperclass(testService.getClass());
        MethodInterceptor methodInterceptor = (o, method, args1, methodProxy) -> {
            //等同于 InvocationHandler ---invoke
            System.out.println(" log= ");
            Object invoke = method.invoke(testService, args1);
            return invoke;
        };

        enhancer.setCallback(methodInterceptor);

        TestService o = (TestService) enhancer.create();
        o.login("yjy", "123");
    }
}

运行结果:
在这里插入图片描述

4. 总结

  1. JDK动态代理 Proxy.newProxyInstance() 通过接?创建代理的实现类
  2. Cglib动态代理 Enhancer 通过继承?类创建的代理类

若有错误,希望大佬指出。

对你有帮助给点个👍再走呗。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 11:39:48  更:2022-04-28 11:41:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:53:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码