JDK动态代理

JDK动态代理

总结:

1.代理模式:

当一个对象不能直接使用时,可以在客户端和目标类之间直接创建一个中介,这个中介就是一个代理

2.作用:

1)控制访问:在代理中,控制是否可以调用目标对象的方法

2)功能增强:可以在完成目标对象的调用时,附加一些额外的功能。这些额外的功能就是功能增强

3.代理的实现方式:

1.静态代理:代理类是手工实现的Java文件,同时代理的目标对象是规定的

1)优点:容易理解使用方便

2)缺点:在目标类比较多的时候,会产生大量的代理类,到接口改变时,影响目标类的代码实现,需要修改代码,影响较多。

2.动态代理:

1)不用创建代理类

2)可以给不同的目标类随时创建代理

详细说明:

JDK动态代理

动态代理:基于反射机制

1代理

代购,中介,商家等等

比如有一个厂家要卖衣服,可以卖给任何一个人,淘宝商家,实体店(代理)

淘宝店铺(代理):帮助这个生产厂家卖衣服,淘宝是厂家的代理,淘宝是代替厂家卖衣服的功能。

代理的特点:

1.淘宝和厂家他们要做的事情是一样的,卖衣服

2.淘宝是厂家的代理,厂家是目标。

3.顾客--淘宝--厂家

4。淘宝是代理,不能白干活,需要获取利润

为什么要找淘宝:

1.淘宝方便,不用去找生产厂家

2.用户没有能力直接从厂家直接卖衣服

买东西都是商家卖,商家就是某一种商品的代理,你个人买东西是接触不到厂家的

2.在开发中,你有A类本来是调用C类的方法完成某种功能

但是A不能直接调用C类

现在在A类和C类中间创建一个B类

B类就相当于一个代理让B类访问C类

实际例子:登录,注册需要验证码,验证码是手机短信

中国移动中国联通发送短息

中国移动,中国联通的子公司,或者关联公司她们面向社会体用发送短信业务

张三项目发送短信------子公司,或者关联公司-----中国移动,中国联通

代理模式:

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

使用代理模式的作用

1.功能增强:在原有的功能的基础上,增加了额外的功能。新增加的功能,叫做功能增强

2.控制访问:代理类不让你访问目标,例如商家不让你直接接触厂家

实现代理的方式

1:静态代理

1)代理类是自己手动实现 的,自己创建一个Java类表示代理类

2)同时你所代理的的目标类是确定的

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

缺点:当目标类增加了,代理类可能也需要成倍增加,代理类数量过多

当你的接口中功能增加了,或者修改了,会影响众多的实现类,目标类,代理都需要修改,影响比较多。

2:动态代理:

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

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

动态代理:在程序执行中,使用jdk的反射机制,创建代理类的对象,并动态的指定代理目标类

换句话:动态代理是一种创建Java对象的能力,让你不用创建TAOBAO类,就可以创建代理类的对象

在Java中,想要创建对象:

1.创建类文件,Java文件编译为class文件

2.使用构造方法,创建类的对象

动态代理的实现:1.jdk动态代理:使用Java反射包中的类和接口的事项动态代理的功能

反射包Java.lang.reflect,里面的三个类:InvocationHandler,Method,proxy

2.cglib动态代理:cglib是第三方的工具库:创建代理类

cglib的原理是继承,cglib通过继承目标类,创建它的子类,在子类中重写父类的同 名方法,实现功能的修改。因为cglib时继承,重写方法,所以要求目标类不能是final的,方法也不能是final,cglib的要求目标类比较宽松,只要可以继承就可以,cglib在很多框架中使用,比如mybatis,spring中

在介绍动态代理之前我们先看一个静态代理的例子:

1.首先我们先创建一个u盘的接口实现卖东西的方法:

package com.zzjm.Service;


//定义一个接口实现卖u盘的方法
//表示功能的,商家和厂家都要执行
public interface UsbSell {
    //定义参数方法,amount表示购买数量;返回值表示u盘价格;
    float sell(int amount);
}

2.我们创建一个目标类来实现接口卖东西的方法:

package com.zzjm.factory;

import com.zzjm.Service.UsbSell;
//表示商家的价格
//厂家继承接口的方法实现卖u盘的方法
public class SanUsb implements UsbSell {
//参数表示卖出优盘的数量
    //返回值是总价
    @Override
    public float sell(int amount) {
        float pire = 0;
        if (amount<100) {
             pire = amount * 85.0f;//表示如果购买数量小于100商家卖出一个是85元
        }else if(amount>=100){
            pire = amount * 75.0f;//表示如果购买数量大于100商家卖出一个是75元
        }
        return pire;//返回的价格是购买u盘的总价
    }
}

3.我们床架代理类实现功能增强(给u盘增加价格)

package com.zzjm.TaoBao;

import com.zzjm.Service.UsbSell;
import com.zzjm.factory.SanUsb;

public class taobaosell implements UsbSell {
    private UsbSell usbSell=new SanUsb();//实例化厂家(目标类)向厂家进货
    @Override
    public float sell(int amount) {
        //卖给用户
       float pire= usbSell.sell(amount);
             pire=pire+amount*10;//没见商品加价10元
        return pire;
    }
}

4.下面我们模仿顾客购买u盘:

package com.zzjm;

import com.zzjm.TaoBao.taobaosell;

import java.lang.reflect.Proxy;

public class MyApp {
    public static void main(String[] args) {
        taobaosell taobaosell=new taobaosell();
        float pirce=taobaosell.sell(10);
        System.out.println("需要支付的价格是"+pirce);

   }
}

JDK动态代理:

jdk动态代理采用反射机制来实现:

1.反射:Method类,表示方法,类中的方法,通过Method可以执行这个方法。

2.jdk动态代理的实现

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

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

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

代理类要完成的功能:

1.调用目标方法:

2.功能增强,在调用目标方法的同时,增强功能。

方法原理:

参数

Obiect proxy:jdk创建的代理对象,无需赋值

Method method:目标类中的方法,jdk提供method对象

Object[]args:目标类中的方法参数,jdk提供

public Object invoke(Obiect proxy,Method method,Object[]args)

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

怎么用:1.创建类实现的接口InvocationHandler

2.重写invoke方法,把原来静态代理中代理要完成的功能,写在这。

Method类:表示这个方法,确切说就是目标类中的方法

作用:通过这个method可以执行某个目标类的方法,Method.invoke();

method.invoke(目标对象,方法参数)

Object obiect=method.invoke(sayHello,"张三");

说明:method.invoke()就是用来执行目标方法的,等于静态代理中的

float pirce=taobaosell.sell(10);

proxy类:核心的对象,创建代理类,之前创建的对象都是new 类的构造方法

而现在我们使用proxy类的方法,代替new的使用

方法:静态方法newProxyInstance()

作用:床架代理对象,等同于静态代理中的Taobao taobao=new TaoBao()

参数:

1.ClassLoader loader类加载器,负责向内存中加载对象的,使用反射机制获取对象ClassLoader loader

2. Class<?>[] interfaces:接口,目标对象的实现接口,也是反射获取

3. InvocationHandler h:我们自己写的,代理类要完成的功能。

public static Object newProxyInstance(ClassLoader loader,

Class<?>[] interfaces,

InvocationHandler h)

JDK动态代理的示例:

1.跟静态代理一样首先创建一个实现买东西的接口(方法参数为购买的数量):

package com.zzjm.Service;

public interface Usbsell {
    float sell(int amount);
}

2.创建目标类:

package com.zzjm.factory;

import com.zzjm.Service.Usbsell;

public class UsbKingfactory implements Usbsell {
    @Override
   public float sell(int amount){
        float pirce=0;
        pirce=amount*85;
        return pirce;
    }

}

3.用动态代理的方式实现目标增强的功能(代替了静态代理的淘宝,但是一样实现了功能增强):

package com.zzjm.handler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//必须实现InvocationHandler接口,来完成代理类要做的功能(1.调用方法,2功能增强)
public class MysellHandler implements InvocationHandler {
    private Object trag=null;
//动态代理目标是活动的,需要传入进来
    //传入是谁,谁就是代理对象
    public MysellHandler(Object trag) {
        //给目标对象赋值
        this.trag = trag;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
        Object res=null;
        //向厂家发送订单,告诉厂家我买了u盘,厂家发货
        //float pire= usbSell.sell(amount);
        //商家需要加价,也就是功能增强
        //pire=pire+amount*10;//每件商品加价10元
        //return pire;
        res=method.invoke(trag,args);//执行目标方法。
        if (res!=null){
            Float pirce=(Float)res;
            pirce=pirce+25;
            res=pirce;
        }
        System.out.println("====="+res);
        return res;
    }
}

4.测试购买商品:

import com.zzjm.handler.MysellHandler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class MyAp {
    public static void main(String[] args) {
        //创建代理对象,使用Proxy;
        //1.创建目标对象
        Usbsell factory=new UsbKingfactory();
        //2.创建invocationHandler对象
        InvocationHandler invocationHandler=new MysellHandler(factory);
        //创建代理执行方法
        Usbsell proxy=(Usbsell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),factory.getClass().getInterfaces(),invocationHandler);
        float price=proxy.sell(2);
        System.out.println("总价"+price);
    }

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值