Java代理

一、代理概述

代理是一种Java常用的设计模式,实现代理需要委托类和代理类都有相同的方法。代理提供了对委托类的访问方法,代理类不进行具体的业务逻辑操作,而是调用委托类的相同方法来进行逻辑处理,代理类一般在委托类实现的基础上还能进行一些别的操作。

  • JAVA代理的方法一般分为静态代理和动态代理。

二、静态代理

静态代理指代理类在运行前已经知道代理类和委托类的关系。
直接用生活中的例子来看:我需要买一台电脑,我没用能力直接从厂商那里购买,只能通过京东淘宝等平台来购买,这里我就是一个用户,京东淘宝平台上的上架就是代理,电脑厂家就是目标对象。

1、定义业务

定义一个卖电脑的接口

package Proxy;

public interface ComputerSale {
    float sellComputer();
}

2、定义实现接口的实现类

有厂商生产了电脑要卖出去

package Proxy;

public class HpComputer implements ComputerSale{
    @Override
    public float sellComputer() {
        return 5000.0f;
    }
}

3、定义代理

代理从厂商拿货卖出去,这里直接以TaoBao为例

package Proxy;

public class TaoBao implements ComputerSale{
    private ComputerSale factory = new ComputerFactory();

    @Override
    public float sellComputer() {
        float price = factory.sellComputer();
        return price + 1500;
    }
}

这两家都是代理销售电脑的代理类

4、定义消费者类来购买电脑

消费者可以通过TaoBao来购买电脑

package Proxy;

public class ProxyTest {
    public static void main(String[] args) {
        TaoBao taoBao = new TaoBao();
        float price2 = taoBao.sellComputer();
        System.out.println("taobao's price is: " + price2);
    }
}

5、运行结果

以下是运行结果
在这里插入图片描述

6、优缺点

通过上述的代码可以看出静态代理实现很简单,其实和组合继承之类的差不多也利于理解,但是实际使用中我们可能并不知道委托和代理的具体关系,并且如果接口增加了方法,那么除了目标类要实现这个方法,每个代理类都得相应的实现该方法,增加了维护的难度。

三、动态代理

为了解决静态代理必须实现接口所有方法的问题,我们可以用动态代理来实现,有两种方法

1、JDK动态代理

JDK的动态代理只能代理接口

实现步骤

通过实现 InvocationHandler 接口创建自己的调用处理器
通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类
通过反射机制获得动态代理类的构造函数(jdk自带,不需手动处理)
通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入(jdk自带,不需手动处理)

创建调用处理器

package Proxy;

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

public class SellHandle implements InvocationHandler {
    private Object target = null;

    public SellHandle(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 目标对象
        Object result = null;
        result = method.invoke(target,args);

        // 功能增强 简化一下 统一加价
        if (null != result){
            float price = (float)result;
            price += 1000;
            result = price;
        }

        return result;
    }
}

模拟购买

package Proxy;

import java.lang.reflect.Proxy;

public class ProxyTest {
    public static void main(String[] args) {
        // 创建厂商对象
        ComputerFactory computerFactory = new ComputerFactory();
        // 创建代理处理对象
        SellHandle sellHandle = new SellHandle(computerFactory);

        // 获取目标类的类加载器,实现接口等信息
        Class clazz = computerFactory.getClass();
        ClassLoader classLoader = clazz.getClassLoader();
        Class<?>[] InterFace = clazz.getInterfaces();

        // 创建代理对象
        ComputerSale computerSale = (ComputerSale) Proxy.newProxyInstance(classLoader,InterFace,sellHandle);
        //通过代理对象执行方法
        float price = computerSale.sellComputer();
        System.out.println(price);
    }
}

原理

生成一个代理类,这个代理类继承Proxy类并且实现了我们定义的接口,代理对象调用方法的时候,调用这个代理对象的一个成员InvocationHandler(上面我们传入了一个InvocationHandler实现对象)的方法,也就是我们包装了委托类后的方法。

2、cglib实现动态代理

暂时咕咕咕

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值