Java的动态代理的使用

原接口与对象

ProducerInterface.java
 

public interface ProducerInterface
{
    /*
     * @Author chensy
     * @Description //TODO 销售
     * @Date 11:11 2019/4/22
     * @Param [money]
     * @return void
     **/
     void saleProduct(float money);
    /*
     * @Author chensy
     * @Description //TODO 售后
     * @Date 11:11 2019/4/22
     * @Param [money]
     * @return void
     **/
     void afterService(float money);

}

Producer.java
 

package com.itheima.proxy;/*
 *@program: springDay03_user
 *@description: 动态代理对象, 生产者
 *@author: chensy
 *@create: 2019-04-22 11:09
 */

public class Producer implements ProducerInterface
{
    /*
     * @Author chensy
     * @Description //TODO 销售
     * @Date 11:11 2019/4/22
     * @Param [money]
     * @return void
     **/
    public void saleProduct(float money){
        System.out.println("销售产品,拿到钱 : " + money);
    }

    /*
     * @Author chensy
     * @Description //TODO 售后
     * @Date 11:11 2019/4/22
     * @Param [money]
     * @return void
     **/
    public void afterService(float money){
        System.out.println("提供售后服务,并拿到钱 :" + money);
    }

}

1).基于接口的动态代理

       涉及的类:  Proxy
       提供者:     JDK官方

  1.  如何创建代理对象:
    使用Proxy类中的newProxyInstance方法
  2. 创建代理对象的要求:
    被代理类最少实现一个接口
  3. newProxyInstance方法的参数
     
    ClassLoader :  类加载器
             它是用于加载代理对象字节码. 和被代理对象使用相同的类加载器.
    Class[]:           字节码数组
             它是用于让代理对象和被代理对象有相同的方法
    InvocationHandler:       用于提供增强的代码
             它是让我们写如何代理. 
  4. 代理对象代码:
    public class client
    {
        public static void main(String[] args) {
            final Producer producer = new Producer();
            /*
             * @Author chensy
             * @Description //TODO 增强原对象功能
             * @Date 12:40 2019/4/22
             * @Param [args]
             * @return void
             **/
            ProducerInterface proxyProducer = (ProducerInterface) Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(), new InvocationHandler() {
    
                /*
                 * @Author chensy
                 * @Description 执行被代理对象的任何接口都会经过该方法
                 * @Date 12:41 2019/4/22
                 * @Param     1.proxy  代理对象的引用
                 *            2.method 当前执行的方法
                 *            3.args   当前执行的方法所需的参数
                 *
                 * @return java.lang.Object
                 **/
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object o = null;
                    if(method.getName().equals("saleProduct"))
                    {
                        Float money = (Float) args[0];
                        o = method.invoke(producer, money * 0.8f);
                    }
                    return o;
                }
            });
    
            //执行代理对象的函数
            proxyProducer.saleProduct(1000f);
        }
    }
    

   5.结果
                     结果发现, 没有修改原代码的情况下, 使输出的钱减少了        

 

2).基于子类的动态代理

  1.       基于第三方jar包(cglib)
      Maven坐标:  
              
    <dependency>
        <groupId>org.sonatype.sisu.inject</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.1-v20090111</version>
    </dependency>
  2.   涉及类: Enhancer
      创建方法:  Enhancer.create
  3.   被代理的不能是最终类
  4.   代理代码: 
    public class client
    {
        public static void main(String[] args) {
            final Producer producer = new Producer();
    
            Producer cglibProducer = (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor() {
    
                /*
                 * @Author chensy
                 * @Description
                 * @Date 12:49 2019/4/22
                 * @Param     o:  代理对象的引用
                 *            method:   当前执行的方法
                 *            objects    当前执行的方法所需的参数
                 *            methodProxy:  当前执行的方法的代理对象
                 * @return java.lang.Object
                 **/
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    Object object = null;
                    if(method.getName().equals("saleProduct"))
                    {
                        Float money = (Float) objects[0];
                        System.out.println("经过代理对象前 Money=" + money);
                        o = method.invoke(producer, money * 0.8f);
                    }
                    return o;
                }
            });
    
            cglibProducer.saleProduct(1000f);
        }
    }

    5. 结果:
           同样得到相同的结果, 不过被代理的类并没有实现接口
    6.Producer.java
       

    public class Producer
    {
        /*
         * @Author chensy
         * @Description //TODO 销售
         * @Date 11:11 2019/4/22
         * @Param [money]
         * @return void
         **/
        public void saleProduct(float money){
            System.out.println("销售产品,拿到钱 : " + money);
        }
    
        /*
         * @Author chensy
         * @Description //TODO 售后
         * @Date 11:11 2019/4/22
         * @Param [money]
         * @return void
         **/
        public void afterService(float money){
            System.out.println("提供售后服务,并拿到钱 :" + money);
        }
    
    }
    

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值