动态代理的两种实现方法(基于接口的动态代理、基于子类的动态代理)

概述

  什么是代理。个人认为就是我们常说的:中间商赚差价。
  在以往的消费模式中,往往都是消费者直接联系生产者,但这个时候生产者又要生产产品、又要保证售后。给生产者带来了一个非常大的一个压力。因此,随着时代进步,中间商这个群体出现了,他们联系生产者,这个时候生产者只负责生产东西,中间商负责售后。保证了效率,消费者的权益也得到了保障。
代理

特点

  字节码随用随创建,随用随加载。

作用

  在不修改源码的情况下,对功能进行一个增强。

分类

  1. 基于接口的动态代理
  2. 基于子类的动态代理

基于接口的动态代理

  1. 定义一个接口IProducer,用于实现类使用
package one_interface;

public interface IProducer {
    /**
     * 销售
     */
    public void sale(double money);

    /**
     * 售后
     */
    public void service(double money);
}
  1. 定义一个类Producer,实现该接口
package one_interface;

public class Producer implements IProducer{

    /**
     * 销售
     */
    public void sale(double money){
        System.out.println("卖了东西,拿到:"+money);
    }

    /**
     * 售后
     */
    public void service(double money){
        System.out.println("由于质量出现问题,包修、换,花了:"+money);
    }

}

  1. 编写简易生产者、消费者用于中间商赚差价主函数client
    1. 使用proxy的一个静态方法newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
    2. 具体参数如下表所示
参数含义作用
ClassLoader类加载器它是用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法。
Class<?>[]字节码数组它是用于让代理对象和被代理对象有相同方法。固定写法。
InvocationHandler提供增强的代码它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须
package one_interface;

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

public class Client {
    public static void main(String[] args) {
        final Producer producer = new Producer();
        // 中间商赚差价
        IProducer iProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
                producer.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * 作用:执行被代理对象的所有接口方法,都会经过这里。执行invoke方法
                     * @param proxy        代理对象的引用
                     * @param method       当前执行方法
                     * @param args         当前执行方法的参数
                     * @return             和被代理对象方法有相同的返回值
                     * @throws Throwable
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 开始赚差价
                        Object obj = null;
                        // 中间商。从消费者拿到钱。自己收一部分,再给生产者
                        if("sale".equals(method.getName())){
                            Double money = (Double)args[0];
                            obj = method.invoke(producer,money*0.8);
                        }
                        return obj;
                    }
                });

        iProducer.sale(10000);
    }
}

基于子类的动态代理

  1. 需要依赖cglib包,因此要导入
    建议使用maven工程,联网之后检索配置下有无该包,如果没有即可自动导入。如下所示:
	<dependencies>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.4</version>
        </dependency>
    </dependencies>
  1. 直接写类。无需继承。如下所示:
package two_ziclass;

public class Producer{

    /**
     * 销售
     */
    public void sale(double money){
        System.out.println("卖了东西,拿到:"+money);
    }

    /**
     * 售后
     */
    public void service(double money){
        System.out.println("由于质量出现问题,包修、换,花了:"+money);
    }

}

  1. 编写简易生产者、消费者用于中间商赚差价主函数client
    1. 使用Enhancer的一个静态方法create(Class type, Callback callback)
    2. 具体参数如下表所示
参数含义作用
Class字节码他是用于指定被代理对象的字节码
Callback提供增强的代码让我们写如何代理。一般使用该接口的实现类:MethodInterceptor
package two_ziclass;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;


public class Client {
    public static void main(String[] args) {
        final Producer producer = new Producer();
        // 中间商赚差价
        Producer cglibProducer = (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
        	/**
             * 作用:执行被代理对象的所有方法,都会经过这里。执行intercept方法
             * @param o
             * @param method
             * @param objects
             *          前三者和基于接口的动态代理含义一模一样
             * @param methodProxy
             *          当前执行的代理对象
             * @return
             * @throws Throwable
             */
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                // 开始赚差价
                Object obj = null;
                // 中间商。从消费者拿到钱。自己收一部分,再给生产者
                if("sale".equals(method.getName())){
                    Double money = (Double)objects[0];
                    obj = method.invoke(producer,money*0.8);
                }
                return obj;
            }
        });
        cglibProducer.sale(20000);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值