详解JDK动态代理使用及原理

一.代理模式

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

二.使用代理模式的作用

  1. 功能增强:在不改变目标方法的前提下,通过代理增加额外的功能。
  2. 控制访问:代理类不让你直接访问目标

三.实现代理的方式

1.静态代理

(1)特点

a.代理是你手工实现的,自己创建一个Java类,代表代理类
b.你要代理的目标类是明确的
c.实现简单,容易理解

(2)举例(用户购买商品的行为)

用户:客户端类
商家:代理,代理某个商品
厂家:目标类

实现步骤:
a.创建一个接口,定义卖东西的行为
b.创建厂家类,实现步骤a中的接口
c.创建商家类,也就是代理,实现步骤a中的接口
d.创建用户类,调用商家类的方法购买东西

代理类实现的功能:
a.调用目标类的方法
b.功能增强

(3)缺点

当项目中目标类和和代理类很多的时候
a.当目标类增加时,代理类可能要成倍的增加
b.当接口中功能增加或修改时,会影响众多的代理类和目标类

2.动态代理

(1)特点

在程序运行过程中,通过jdk的反射机制,创建代理类对象,并动态的指定其目标类。
即就是一种创建java对象的能力,让你不用手动去创建代理类。

(2)实现

jdk动态代理

使用Java反射包中的类和接口实现动态代理
java.lang.reflect中有三个类/接口:InvocationHandler,Method,Proxy

a. InvocationHandler接口(调用处理器)

其中只有一个方法:invoke() :代理对象要执行的功能代码
方法原型
public object invoke(object proxy,Method method,Object args)
参数
object proxy : jdk创建的代理对象
Method method:目标类中的方法,是jdk提供method对象的
Object[] args:目标类中方法的参数,jdk提供的
使用
(1)创建类实现InvocationHandler接口
(2)重写invoke()方法,将代理类要实现的功能写入invoke()中

b. Method类

作用:执行某个目标类的方法

method.invoke(目标对象,方法的参数);
method.invole(service,"张三");
c. Proxy类

作用:创建代理对象
方法:静态方法public static Object newProxyInstance()

//方法原型
//该方法返回值就是代理对象
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

参数说明:

ClassLoader loader
类加载器,向内存中加载对象,通过反射机制获取对象的ClassLoader,是目标对象的类加载器。

//a类
a.getClass().getClassLoader();

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

InvocationHandler h
是我们自己写的代理类要实现的功能

d.实现步骤

1.创建接口,定义目标类要实现的功能

package com.xhy.service;

//目标接口
//售卖u盘的功能
public interface usbSell {
    float sell(int amount);
}

2.创建目标类实现接口

package com.xhy.factory;

import com.xhy.service.usbSell;

//目标类
//u盘厂家实现卖u盘的功能
public class usbkingFactory implements usbSell {
    @Override
    //目标方法
    //amount是购买数量
    public float sell(int amount) {
        System.out.println("目标类执行了sell目标方法!");
        
        return 65.0f; //u盘的厂家价格
    }
}

3.创建InvocationHandler的实现类,在invoke方法中实现代理对象的功能

package com.xhy.handler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//实现InvocationHandler接口,完成代理类的功能
//1.实现目标方法
//2.功能增强
public class mysellHandler implements InvocationHandler {

    private Object target = null;

    //动态代理,目标对象是动态的,是由你自己传入的,传入的对象是谁,就给谁创建代理
    public mysellHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object res = null;

        //1.执行目标方法
        //向厂家发送订单,厂家发货
        res = method.invoke(target,args); //厂家的价格

        //2.功能增强
        //商家(代理)需要加价,并且赠送买家优惠券
        if (res !=null){
            Float price = (Float) res;
            price = price +30;
            res = price;
        }

        System.out.println("商家赠送了一张五元优惠券");

        //商家加价后的新价格
        return res;

    }
}

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

import com.xhy.factory.usbkingFactory;
import com.xhy.handler.mysellHandler;
import com.xhy.service.usbSell;

import java.lang.reflect.Proxy;

public class mainShop {
    public static void main(String[] args) {
        //创建代理对象,使用Proxy
        //1.创建目标类对象
        usbkingFactory factory = new usbkingFactory();

        //2.创建InvocationHandler对象
        mysellHandler handler = new mysellHandler(factory);

        //3.创建代理对象
        usbSell proxy = (usbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),
                factory.getClass().getInterfaces(),
                handler);

        //4.通过代理对象,调用目标方法
        //商家加价后的价格
        float price = proxy.sell(1);
        System.out.println("通过代理对象调用了目标方法(商家向厂家发送了订单):"+price);
    }
}
//呼,好累啊好累啊

5.执行结果

目标类执行了sell目标方法!
商家赠送了一张五元优惠券
通过代理对象调用了目标方法(商家向厂家发送了订单):95.0
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值