jdk动态代理

动态代理

使用反射机制,在内存中创建代理类的对象,不用你写java文件。
jdk动态代理,必须有接口,目标类必须实现接口, 没有接口时,需要使用cglib动态代理

作用

1.功能增强: 在你原有的功能上,增加了额外的功能。 新增加的功能,叫做功能增强。
2.控制访问: 代理类不让你访问目标,例如商家不让用户访问厂家。

实现代理的方式

1.静态代理 :

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

特点: 1)实现简单 2)容易理解。
缺点:
当你的项目中,目标类和代理类很多时候,有以下的缺点:
1)当目标类增加了, 代理类可能也需要成倍的增加。 代理类数量过多。
2) 当你的接口中功能增加了, 或者修改了,会影响众多的实现类,厂家类,代理都需要修改。
影响比较多。

2.动态代理

优点:

1) 动态代理中目标类即使很多, 代理类数量可以很少,
2)当你修改了接口中的方法时,不会影响代理类。

动态代理 :

在程序执行过程中,使用jdk的反射机制,创建代理类对象, 并动态的指定要代理目标类。
换句话说: 动态代理是一种创建java对象的能力,让你不用创建代理类,就能创建代理类对象。

在java中,要想创建对象:
1.创建类文件, java文件编译为class
2.使用构造方法,创建类的对象。

动态代理的实现:

1. jdk动态代理(理解): 使用java反射包中的类和接口实现动态代理的功能。

反射包 java.lang.reflect , 里面有三个类 : InvocationHandler , Method, Proxy.

1)InvocationHandler 接口(调用处理器):就一个方法invoke()

invoke():表示代理对象要执行的功能代码。你的代理类要完成的功能就写在invoke()方法中。
代理类完成的功能:
1. 调用目标方法,执行目标方法的功能
2. 功能增强,在目标方法调用时,增加功能。

2)Method类:表示方法的, 确切的说就是目标类中的方法。
3)Proxy类:核心的对象,创建代理对象。

之前创建对象都是 new 类的构造方法(),现在我们是使用Proxy类的方法,代替new的使用。

实现动态代理的步骤:
  1. 创建接口,定义目标类要完成的功能
  2. 创建目标类实现接口
  3. 创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
    1.调用目标方法
    2.增强功能
  4. 使用Proxy类的静态方法,创建代理对象。 并把返回值转为接口类型。
    方法: 静态方法 newProxyInstance()
    作用是: 创建代理对象, 等同于静态代理中的TaoBao taoBao = new TaoBao();

动态代理原理

动态代理,就是不能直接访问实例对象,做一个中介,代理实例对象的具有的属性和方法,这样我们也可以做到
访问实例对象(间接的访问)。
创建代理对象,要调用proxy类的静态方法newProxyIntance(),参数有三个,

  1. 目标类的加载器,(实例化目标对象之后,通过 实例对象.getclass().getclassCloader()获得
  2. 目标类所实现的接口,(实例化目标对象之后,通过 实例对象.getclass().getInterface()获得
  3. 处理器,创建一个代理类,此代理类实现InvocationHandler接口,通过重写接口中的方法invoke(Object proxy,
    Method method, Object[] args),这三个参数都是在实例化代理类对象后,jdk传入的。重写invoke方法时,会调用参数
    对象的invoke()方法,这两个方法只是恰好同名,没有丝毫关系。此时就是调用目标对象的方法,此时,也可以加写新的方法,也就是增强目标类的功能。处理器,本质就是代理类,生成一个与目标类一样或更多功能的类,而且是动态的。
    newProxyIntance()执行之后就会产生一个目标类的代理对象,此时可以通过对代理对象的操作以达到对目标对象的
    访问。
    整体思路就是,现在有一个实例对象,创建一个代理对象,代理对象复制了实例对象,并且可以做到具有更多功能,
    操作代理对象,就操作了实例对象。
2. cglib动态代理(了解): cglib是第三方的工具库, 创建代理对象。

cglib的原理是继承, cglib通过继承目标类,创建它的子类,在子类中 重写父类中同名的方法, 实现功能的修改。 因为cglib是继承,重写方法,所以要求目标类不能是final的, 方法也不能是final的。
cglib的要求目标类比较宽松, 只要能继承就可以了。cglib在很多的框架中使用,
比如 mybatis ,spring框架中都有使用。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值