文档章节

动态代理知识详解

我叫小糖主
 我叫小糖主
发布于 05/22 19:17
字数 1242
阅读 18
收藏 0

动态代理实现的两种方式

给动态代理举个栗子:例如我们平时买笔记本电脑,很多时候都是不从厂家拿货,而是通过经销商买电脑。代理模式出现解决了生产厂家的一些问题,那么这个这个思想在我们编程中是怎么体现的啦???

下面根据具体的案例来解释

目录结构

1、基于接口动态代理

该方式的缺点:如果类不实现接口,代理是无法使用

* 动态代理的特点就是字节码,随用随创建,随用随加载
* 作用:在不修改源码的基础上对方法的增强
* 分类:
*      基于接口动态代理
*      基于子类的动态代理
* 基于接口的动态代理
*      涉及类:proxy
*      提供者:jdk官方
* 如何创建动态代理对象
*      使用proxy中的newProxyInstance方法
* 创建代理对象的要求:
*      被代理的对象至少实现一个接口,如果没有则不能使用
* newProxyInstance方法的参数
* classLoader  用于加载代理对象的字节码,写的是被代理对象的类加载器,和被代理对象使用相同的类加载器(固定写法)
* Class[]   它是用于代理对象和被代理对象有相同的方法(固定写法)
* InvocationHandler 用于增强的代理,含义是写如何代理,我们一般是写一个该接口的实现类,
* 通常情况下是匿名内部类(匿名内部类访问外部成员时,需要用final修饰),但是不必须,都是谁用谁写

案例如下:

接口
package com.cc.proxy;

public interface IProducer {

    public void saleProduct(float money);

    public void afterService(float money);

}
package com.cc.proxy;

/**
 * 一个生产者
 */
public class Producer implements IProducer{
    /**
     * 销售
     */
    public void saleProduct(float money){
        System.out.println("销售产品,拿到钱:"+money);
    }

    /**
     * 售后
     */
    public void afterService(float money){
        System.out.println("提供售后服务,并拿到钱"+money);
    }
}

测试方法

package com.cc.proxy;

import org.junit.Test;

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

/**
 * 模拟一个消费者
 * 基于接口的动态代理,如果类不实现接口代理是无法使用
 */
public class Client {
   @Test
    public void test(){
       final Producer producer=new Producer();
     
       IProducer proxyProducer=(IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(),
               new InvocationHandler() {
                   /**
                    * 作用:执行被代理对象的任何接口的方法都会经过该方法
                    * @param proxy  代理对象的引用
                    * @param method 当前执行的方法
                    * @param args 当前执行该方法所需要的参数
                    * @return 和被代理对象方法具有相同的返回值
                    * @throws Throwable
                    */
           @Override
           public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               //增强的代码
               Object returnValue=null;
               //1、获取方法执行的参数
               Float money= (Float) args[0];
               //2.判断当前方法是不是销售
               if("saleProduct".equals(method.getName())){
                   returnValue=method.invoke(producer,money*0.8f);
               }
                return  returnValue;
           }
       });
               proxyProducer.saleProduct(12000f);

   }
}

2、基于子类的动态代理

/**
 * 动态代理:
 *  特点:字节码随用随创建,随用随加载
 *  作用:不修改源码的基础上对方法增强
 *  分类:
 *      基于接口的动态代理
 *      基于子类的动态代理
 *  基于子类的动态代理:
 *      涉及的类:Enhancer
 *      提供者:第三方cglib库
 *  如何创建代理对象:
 *      使用Enhancer类中的create方法
 *  创建代理对象的要求:
 *      被代理类不能是最终类
 *  create方法的参数:
 *      Class:字节码
 *          它是用于指定被代理对象的字节码。
 *
 *      Callback:用于提供增强的代码
 *          它是让我们写如何代理。我们一般都是些一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的。
 *          此接口的实现类都是谁用谁写。
 *          我们一般写的都是该接口的子接口实现类:MethodInterceptor
 */
package com.cc.cglib;

/**
 * 一个生产者
 */
public class Producer {
    /**
     * 销售
     */
    public void saleProduct(float money){
        System.out.println("销售产品,拿到钱:"+money);
    }

    /**
     * 售后
     */
    public void afterService(float money){
        System.out.println("提供售后服务,并拿到钱"+money);
    }
}
package com.cc.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;

import java.lang.reflect.Method;

/**
 * 模拟一个消费者
 */
public class Client {
    @Test
    public void test(){
            final Producer producer = new Producer();

            Producer cglibProducer = (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() {
                /**
                 * 执行北地阿里对象的任何方法都会经过该方法
                 * @param proxy
                 * @param method
                 * @param args
                 *    以上三个参数和基于接口的动态代理中invoke方法的参数是一样的
                 * @param methodProxy :当前执行方法的代理对象
                 * @return
                 * @throws Throwable
                 */
                @Override
                public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                    //提供增强的代码
                     Object returnValue=null;
                    //1.获取方法执行的参数
                    Float money=(float)args[0];
                    //2.判断当前方法是不是销售
                    if("saleProduct".equals(method.getName())){
                        returnValue=method.invoke(producer,money*0.8f);
                    }
                    return returnValue;
                }
            });
            cglibProducer.saleProduct(12000f);
        }
}

测试结果如下:

 

© 著作权归作者所有

我叫小糖主
粉丝 6
博文 44
码字总数 51148
作品 0
大渡口
私信 提问
java的动态代理机制详解

在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能...

小风89
2016/06/28
25
0
SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架

1 JDK动态代理详解   静态代理、JDK动态代理、Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文。   1.1 JDK代理的基本步骤     》通过实现InvocationHandler接口来自定义自...

CRUD_Architect
2018/08/23
0
0
java的动态代理机制详解

在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能...

Zhang_Java
2016/11/17
5
0
Android Hook 机制之简单实战

简介 什么是 Hook Hook 又叫“钩子”,它可以在事件传送的过程中截获并监控事件的传输,将自身的代码与系统方法进行融入。这样当这些方法被调用时,也就可以执行我们自己的代码,这也是面向切...

xujun9411
2018/09/05
0
0
Java动态代理 深度详解

文章首发于【博客园-陈树义】,点击跳转到原文深入浅出Java动态代理 代理模式是设计模式中非常重要的一种类型,而设计模式又是编程中非常重要的知识点,特别是在业务系统的重构中,更是有举足...

陈树义
2017/11/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

关于对json的理解

下面是php代码 $data = [ "dataList"=>[ [ "id"=>0, "name"=>"名字1" ], [ "id"=>1, "name"=>"名字2" ] ] ]; echo json_encode($data,JSON_UNESCAPED_UNICODE); //输出结果 {"dataList":[{"i......

chenhongjiang
17分钟前
0
0
5.02-Navicat premium激活

http://www.downcc.com/soft/322714.html

静以修身2025
17分钟前
0
0
Qt类图表组件QtitanChart发布v6.0.0 beta 1|支持Qt 5.12

QtitanChart是一个包含多种控件的C++类库,能为您的应用提供漂亮、色彩鲜艳的图表。QtitanChart是基于Qt.C++实现的,支持所有主流的操作系统- Windows、Linux和Mac OS X。只需几行代码就可以...

FILA6666
17分钟前
1
0
宜人贷PaaS数据服务平台Genie:技术架构及功能

上篇:架构及组件 一、数据平台的发展 1.1 背景介绍 随着数据时代的到来,数据量和数据复杂度的增加推动了数据工程领域的快速发展。为了满足各类数据获取/计算等需求,业内涌现出了诸多解决方...

宜信技术学院
18分钟前
1
0
golang testify 测试库

项目日志 https://github.com/stretchr/testify

electricface
18分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部