Spring学习——动态代理(jdk)

1.代理

中介,黄牛,商家平台

eg:某多多,商家跟工厂批量进货,卖给你;

代理特点:

1.中介和代理他们要做的事情是一致的:东西卖出去。

2.某多多是工厂代理,客户是目标。

3.中介是代理,不能白干活,需要收取费用(加价)

4.代理不让你访问到目标。

2.代理模式

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

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

客户类真正的想要访问的对象是目标对象,但客户类真正可以访问的对象是代理对象

客户类对目标对象的访问是通过访问代理对象来实现的,当然,代理类与目标类要实现同一个接口。

2.1使用代理模式的作用:

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

2.控制访问: 代理类不让你访问目标,例如商家不让用户访问厂家。

静态代理

静态代理较为简单,直接上代码

客户:

public class Client {
    public static void main(String[] args) {
        PDD pdd = new PDD();
        int price = pdd.sell(1);
        System.out.println("买一个u盘的单价" +price+"元");
    }
}

工厂:

public class factory implements SellService {

    //100元一个,以nums个一起进货
    @Override
    public int sell(int nums) {

        System.out.println(" 目标类中的方法调用,Factory中的sell");
        return nums*100;
    }
}

某平台(代理)

public class PDD implements SellService{
    //声明 商家代理的厂家具体是谁
    private factory f=new factory();


    int nums=100;
    @Override
    public int sell(int nums) {

        //向厂家发送订单,告诉厂家,我买了U盘,厂家发货
        int price;//厂家的价格
        price = f.sell(nums);
        //加价卖出
        price=price+10;

        return price;
    }
}

接口

public interface SellService {
    public int sell(int nums);
}

动态代理

  • jdk动态代理:使用java反射包中的类和对象实现动态代理的功能。

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

  1. InovcationHandler.接口:

就一个方法invoke()

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

代理类完成的功能:

1)调用目标方法,执行目标方法的功能。

2)功能增强,在目标方法调用时,增强功能。

方法原型:public Object invoke(Object proxy, Method method, Object[] args)

参数:

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

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

Object[] args:目标类中方法的参数

怎么用:

1.创建类实现接口InovcationHandler

2.重写invoke()方法,把原来静态代理中代理类要完成的功能,卸载这里。

  1. Method类:

表示方法的,确切的说就是目标类中的方法。

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

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

Object ret =method.invoke(service2,“李四”);

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

//向厂家发送订单,告诉产假,我买了U盘,厂家发货

float price = factory.sell(amount);//厂家的价格

  1. Proxy类:

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

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

方法:静态方法newProxyInstance()

作用是:创建代理对象,等同于静态代理中的TaoBao taoBao = new TaoBao();

参数:

1.ClassLoader loader 类加载器,负责向内存中加载对象的。使用反射获取对象的ClassLoader类a,a.getClass().getClassLoader(),目标对象的类加载器

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

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

返回值:就是代理对象。

public static Object newProxyInstance(ClassLoader loader,

Class<?>[] interfaces,

InvocationHandler h)

3.实现动态代理的步骤:

1)创建接口,定义目标类要完成的功能

2)创建目标类实现接口

3)创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能(调用目标方法,增强功能)

4)使用Proxy类的静态方法,创建代理对象。并把返回值转为接口类型。

例子:

动态代理接口类

public interface SellService {
    public void  sell();
}

目标类

ublic class Factory implements SellService {

    //100元一个,以nums个一起进货
    @Override
    public void sell() {
        System.out.println(" 目标类中的方法调用,Factory中的sell");
    }
}

动态代理类


// 动态代理类
public class ProxyInvocationHandler implements InvocationHandler {

    //动态代理类拿到 抽象角色:出售
    private SellService sellService;

    public void setSellService(SellService sellService) {
        this.sellService = sellService;
    }


    //生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                sellService.getClass().getInterfaces(),this);
    }


    // proxy : 代理类    method : 代理类的调用处理程序的方法对象.
    // 处理代理实例上的方法调用并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //核心:本质利用反射实现!
        Object result = method.invoke(sellService, args);
        return result;
    }

}

Client

public class Client {
    public static void main(String[] args) {

        Factory factory = new Factory();
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setSellService(factory);
        SellService proxy = (SellService) pih.getProxy();
        proxy.sell();
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值