详细分析java 动态代理

1、动态代理的特点:

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

2、作用:

不修改源码的基础上对源码进行加强

3、分类:

(1)基于接口的动态代理:

涉及到的类:Proxy,由JDK官方提供,使用Proxy类中的newProxyInstance方法创建对象。创建代理对象时要求被代理对象至少实现一个接口,否则无法使用

参数:

  • ClassLoader:类加载器,他是用于加载对象字节码的,和被代理对象使用相同的类加载器,为固定写法
  • class[]:字节码数组,他是用于让代理对象和被代理对象具有相同的方法,也是固定写法
  • InvocationHandler:用户提供增强的代码 ,他是让我们写如何代理。我们一般都是写一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的,此接口的实现类都是谁用谁写

示例: 创建 Producter接口和实体类

package com.mingqi.proxy;
/**
 * 对生产厂家要求的接口
 */
public interface IProducer {
  /**
   * 销售
   * @param money
   */
  public void SaleProduct(float money);

  /**
   * 售后
   * @param money
   */
  public void AfterService(float money);
}
package com.mingqi.proxy;

public class Producer implements IProducer {
  public void SaleProduct(float money) {
    System.out.println("销售产品,并拿到钱:"+money);
  }

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

测试方法:

public static void main(String[] args) {
 /*   1、动态代理
    特点:字节码随用随创建,随用随加载
    作用:不修改源码的基础上对源码进行加强
    分类:基于接口的动态代理
    涉及的类: Proxy
    提供者:JDK官方
    如何创建代理对象:
    使用Proxy类中的newProxyInstance方法
    创建代理对象的要求:
    被代理对象至少实现一个接口,如果没有则不能使用
    newProxyInstance的方法参数:
    ClassLoader:类加载器
    他是用于加载代理对象字节码的,和被代理对象使用相同的类加载器,固定写法
    class[]  :字节码数组
    InvocationHandler 用于提供增强的代码
    他是让我们写如何代理,我们一般都是写一个接口的实现类,通常情况下都是匿名内部类,但不是必须的,此接口的实现类都是谁用谁写*/
   final Producer producer=new Producer();
   IProdurcer proxyProducer= (IProdurcer)Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(),
       new InvocationHandler() {
         /**
         * 作用:执行被代理对象的任何接口方法都会经过该方法
         * 方法参数的含义
         * @param proxy 代理对象的引用
         * @param method 当前执行的方法
         * @param args  当前执行方法所需的参数
         * @return  被代理对象有相同的返回值
         * @throws Throwable
         */
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
           //提供增强的代码:
           Object returnValue=null;
           //1、获取方法执行的参数
           Float money=(Float) args[0];
           //判断当前方法是否是销售
           if("SaleProduct".equals(method.getName()))
           {
             returnValue=method.invoke(producer,money*0.8f);
           }
           return returnValue;
         }
       });
    proxyProducer.SaleProduct(10000f);
  }

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

涉及到的类:Enhancer,由第三方cglib提供,使用Enhancer类中的create方法创建对象。创建代理对象的类不能是最终类,否则无法使用

参数:

  • Class:字节码,他是用于指定被代理对象的字节码,为固定写法
  • Callback:用户提供增强的代码 ,他是让我们写如何代理。我们一般都是写一个该接口的实现类,通常情况下都是匿名内部类,但不是必须的,此接口的实现类都是谁用谁写,我们一般写的都是该接口的子接口实现类MethodInterceptor

示例: 创建 Product接口和实体类

package com.mingqi.cglib;

/**
 * 一个生产者
 */
public class Product {

  /**
   * 销售
   * @param money
   */
  public void saleProduct(float money){
    System.out.println("销售产品,并拿到钱:"+money);
  }

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

测试类及方法:

package com.mingqi.cglib;
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 Product product=new Product();
    Product cglibproduct= (Product) Enhancer.create(product.getClass(), new MethodInterceptor() {
      public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object returnValue=null;
        //1、获取方法执行的参数
        Float money=(Float)objects[0];
        //判断当前方法是不是销售
        if("SaleProduct".equals(method.getName())) {
          returnValue = method.invoke(product, money*0.8f);
        }
        return returnValue;
      }
    });
    cglibproduct.SaleProduct(1000f);
  }
}

以上就是创建动态代理对象的两种类型,以后要经常练习使用,让这种思想能给我们工作中带来方便。

到此这篇关于详细分析java 动态代理的文章就介绍到这了,更多相关java 动态代理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java使用JDK与Cglib动态代理技术统一管理日志记录

    Java中动态代理主要有JDK和CGLIB两种方式. 区别主要是jdk是代理接口,而cglib是代理类. 优点:这种方式已经解决我们前面所有日记需要的问题.非常的灵活.而且可以方便的在后期进行维护和升级. 缺点:当然使用jdk动态代理,必需要有接口.如果没有接口.就无法使用jdk动态代理技术. 计算接口 Calculate.java public interface Calculate { /** * 加法运算 * @param num1 参数 1 * @param num2 参数 2 * @r

  • Java动态代理(设计模式)代码详解

    基础:需要具备面向对象设计思想,多态的思想,反射的思想: Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对Java动态代理机制有更加深入的理解.本文首先从Java动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 代理模

  • Java动态代理静态代理实例分析

    代理模式:为其他对象提供一种代理以控制某个对象的访问.用在:在某些情况下,一个客户不想或者不能直接访问另一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用,代理对象还可以完成它附加的操作. 例子:就像房东.租客.中介的关系.中介(代理对象)为房东(真实对象)出租房子,租客(客户)通过中介(代理对象)来找房子租房子,中介完成了租房以后可以收取中介费(附加操作). 先看看静态代理模式,通过上面对代理模式的理解,可以了解到代理模式:即不直接通过new一个真实对象来调用方法,而是通过代理对象来

  • Java代理模式实例详解【静态代理与动态代理】

    本文实例讲述了Java代理模式.分享给大家供大家参考,具体如下: 即Proxy Pattern,23种java常用设计模式之一.代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问. Java的代理模式是Java中比较常用的设计模式,分为2中代理:静态代理与动态代理(JDK动态代理和cglib动态代理) 优点: 职责清晰 真实角色只需关注业务逻辑的实现,非业务逻辑部分,后期通过代理类完成即可. 高扩展性 不管真实角色如何变化,由于接口是固定的,代理类无需做任何改动. 缺点: 很明显的一点

  • Java动态代理语法Proxy类原理详解

    1.前言 写动态代理的代码涉及了一个非常重要的类 Proxy,通过Proxy的静态方法newProxyInstance才会动态创建代理对象. 2.newProxyInstance方法 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 三个参数分别表示: loader表示类加载器, interfaces表示代码要用来代理的接口 , h表示一个

  • 详解JAVA动态代理

    文档更新说明 2018年09月24日 v1.0 初稿 代理在生活中很常见,比如说婚介网站,其实就是找对象的代理:还有社保代理.人事代理:还有找黄牛抢票,其实也是一种代理:而这些代理,在JAVA中也是有对应实现的. 1.为什么要动态代理 动态代理的作用其实就是在不修改原代码的前提下,对已有的方法进行增强. 关键点: 不修改原来已有的代码(满足设计模式的要求) 对已有方法进行增强 2.举个栗子 我们用一个很简单的例子来说明:Hello类,有一个introduction方法. 现在我们的需求就是不修改

  • 深入学习Java 动态代理

    前言 要想了解Java动态代理,首先要了解什么叫做代理,熟悉设计模式的朋友一定知道在Gof总结的23种设计模式中,有一种叫做代理(Proxy)的对象结构型模式,动态代理中的代理,指的就是这种设计模式. 在我看来所谓的代理模式,和23种设计模式中的"装饰模式"是一个东西.23种设计模式中将它们作为两种模式,网上也有些文章讲这两种模式的异同,从细节来看,确实可以人为地区分这两种模式,但是抽象到一定高度后,我认为这两种模式是完全一样的.因此学会了代理模式,也就同时掌握了装饰模式. 代理模式

  • Java动态代理和AOP应用示例

    本文实例讲述了Java动态代理和AOP应用.分享给大家供大家参考,具体如下: 一 点睛 动态代理在AOP(Aspect Orient Program,即面向切面编程)里被称为AOP代理,AOP代理可代替目标对象,AOP代理包含了目标对象的全部方法.但AOP代理中的方法与目标对象的方法存在差异:AOP代理里的方法可以在执行目标方法之前.之后插入一些通用处理. 二 代码 Dog.java public interface Dog { // info方法声明 void info(); // run方法

  • JAVA使用动态代理对象进行敏感字过滤代码实例

    这篇文章主要介绍了JAVA使用动态代理对象进行敏感字过滤代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 package com.hopetesting.web.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.BufferedReader; import java.io.FileNotFoundExcepti

  • 深度剖析java动态静态代理原理源码

    正文 关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 静态代理 1.静态代理 静态代理:由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口,被代理类,代理类等确定下来.在程序运行之前,代理类的.class文件就已经生成. 2.静态代理简单实现 根据上面代理模式的类图,来写一个简单的静态代理的例子.我这儿举一个比较粗糙的例子,假如一个班的同学要向老师交班费,但是都是通过班长把自己的钱转交

  • Java动态代理和反射机制详解

    反射机制 Java语言提供的一种基础功能,通过反射,我们可以操作这个类或对象,比如获取这个类中的方法.属性和构造方法等. 动态代理:分为JDK动态代理.cglib动态代理(spring中的动态代理). 静态代理 预先(编译期间)确定了代理者与被代理者之间的关系,也就是说,若代理类在程序运行前就已经存在了,这种情况就叫静态代理 动态代理 代理类在程序运行时创建的代理方式.也就是说,代理类并不是在Java代码中定义的,而是在运行期间根据我们在Java代码中的"指示"动态生成的. 动态代理比

随机推荐