栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

动态代理学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

动态代理学习笔记

在开发中会有这种情况 , 你有a类 , 本来是调用c 类中的方法 , 完成某个功能 , 但是c不让a调用 ,

a ---- 不能调用c的方法

在 a和c中间直接创建一个 b 代理 , c 让 b 访问 , a – 访问 b – b 访问 c

代理模式 :

代理模式是指 , 为其他对象提供一种代理 以控制对这个对象的访问 , 在某些情况下 , 一个对象不适合或者不能直接引用另一个对象 , 而代理对象可以在客户类和目标对象直接起到中介的作用 ,

换句话说 , 使用代理对象 , 是为了在不修改目标对象的基础上 , 增强主业务的逻辑 ,

使用代理模式的作用 :

功能增强 : 在你原有的基础上 ,增加了额外的功能 , 新增加的功能 , 叫做功能增强控制访问 : 代理类不让你访问目标 , 例如 , 实体类中 , 不让直接访问实体类的内容 ,但是添加了get 和set方法 , 用来对内容进行修改 静态代理:

代理类是自己手工实现的 , 自己创建的一个java类 , 代表代理类同时你所要代理的目标是确定的

特点 : 实现简单 , 容易理解

实现步骤 :

创建一个接口 , 定一个方法 , 表示你的厂家和商家要做的事情创建厂家类 , 实现一步骤的接口创建商家 , 就是代理 , 也要实现1步骤中的接口创建客户端类 , 调用商家的方法买 缺点:

当目标类增加了 , 代理类也需要成倍的增加 , 代理类数量过多当你的接口中功能增加了 , 会影响众多的实现类 , 厂家类 , 代理类都需要修改 , 影响比较大


动态代理:

在静态代理中目标类很多的时候 , 可以使用动态代理 , 避免静态代理的缺点

优点 :

动态代理中目标类即使很多 ,

代理类数量可以很少当你修改了接口中的方法时 , 不会影响代理类 动态代理简介 :

基于反射机制 :

​ 使用jdk的反射机制 , 创建对象的能力 , 创建的是代理类的对象 , 而不用你写java对象

换句话说 ,动态代理是一种创建java对象的能力 , 让你不用创建实现类 , 就能创建代理对象

在java中 , 想要创建对象 ,

创建类文件 , java文件编译为class使用构造方法 , 创建类的对象 动态代理的实现分类 :

动态代理分类:

​ 动态代理是指 : 程序在整个运行过程中根本就不存在目标类的代理类 , 目标对象的代理对象只是由代理生成工具(不是真实定义的类) 在程序运行时由JVM根据反射等机制 , 动态生成的 , 代理对象与目标对象的代理关系在程序运行的时候才确立

JDK动态代理 :

动态代理的实现方式常用的有两种 , 使用JDK的Proxy , 和通过CGLIB生成代理

JDK的动态代理要求目标对象必须有实现接口, 这是java设计上的要求

从jdk1.3以来 , java语言通过java.lang.reflect 包提供三个类支持代理模式 Proxy , Method ,和InovcationHandler

CGLID动态代理 :

CGLIB (Code Generation Library)是一个开源项目 , 是一个强大的 , 高性能 ,高质量的Code生成类库

它可以在运行期间扩展java类与实现java接口 , 它广泛的呗许多AOP的框架使用 , 例如Spring AOP

对于无接口的类, 要为其创建动态代理 , 就要使用CGLIB来实现

CGLIB代理的方式是 : 
	生成目标类的子类 , 而子类是增强过的 , 这个子类对象就是代理对象 , 所以使用CGLIB生成动态代理的要求就是 目标类能够被继承 , 即不能是final的类 

CGLIB经常被应用在框架中 , Spring , Hibernate等 cglib代理的效率高于jdk

项目中使用动态代理的地方不多 , 一般都是使用框架提供的功能

JDK动态代理 主要类简介:

反射包中 java.lang.reflect , 里面有三个类 , :

(1) InvocationHandler 接口 ( 中文名称叫做 : 调用处理器 )

这是一个接口 , 在这个接口中只有一个方法 , invoke ()

invoke():表示代理对象要执行的功能代码 , 你的代理类要完成的功能就写在invoke()方法当中

代理类要完成的功能 :

调用目标方法: 执行目标方法的功能功能增加 : 在目标方法调用的时候 , 增加功能

public Object invoke(Object proxy, Method method, Object[] args)
    Object proxy : JDK创建的代理对象 , 无需赋值
	Method method : 目标类中的方法  ,JDK提供的method对象 , 
	Object[] args : 目标类中方法的参数

怎么用 : InvocationHandler 接口 :表示你的代理要干什么

我们要创建一个类 , 实现这个接口重写invoke()方法 , 把原来静态代理中代理类要完成的功能 , 写在这里

(2) Method ()

这是一个类 : 确切的说 , 他就是你的目标类中的方法 ,

作用 : 通过Method可以执行某个目标类的方法 ,

Method.invoke();这个invoke和上边的invoke是不一样的 , 这个只是 Method类中的一个方法

method.invoke(目标对象 , 方法的参数);
通过这个方法 , 可以直接执行这个对象中的方法 , 而不需要知道方法的名称 , 

(3) Proxy : 核心的对象 , 创建代理对象 ,

方法 : newProxyInstance()

作用是 : 创建代理对象

public static Object newProxyInstance(student.getClass().getClassLoader(), student.getClass().getInterfaces(), new InvocationHandler())
    
动态代理实现步骤 JDK :
动态代理的实现步骤 :JDK
1.创建目标类 , SomeServiceImpl 目标类 , 给它的方法进行增强
2.创建InvocationHandler接口的实现类 , 在这个类实现给目标方法增加功能 (或者直接创建内部类也行)
3.使用JDK中类 , Proxy创建代理对象 , 实现创建对象的能力 , 使用代理对象调用目标方法
//使用jdk的Proxy创建代理对象
        //创建目标对象
        SomeService target = new SomeServiceImpl();

        //使用Proxy创建代理
        SomeService proxy = (SomeService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    //通过代理对象执行方法时 , 会调用执行这个invoke()
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("执行了内部类的方法");
                        Object res = null;
                        myUtil.vlog();//增强功能
                        //执行目标类的方法 , 通过Method类实现 , method就是目标方法
                        res = method.invoke(target, args);
                        //执行的是SomeServiceImpl中的方法 , 这里的target就是SomeServiceImpl目标类
                        //SomeService target = new SomeServiceImpl();
                        //arg就是传递过来的值 , 是在下边调用的时候 , 传递的 
                        myUtil.aVoid();//增强功能
                        return res;
                    }
                });
        //proxy就是创建的代理对象 , 这里调用的是什么方法 ,
        // method.invoke(target, args);  执行的就是什么方法
        proxy.doOther();
        //通过代理执行方法 , 会调用上边的中的invoke()方法(继承的那个方法)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/782575.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号