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

所属分类: 软件编程 / java 阅读数: 56
收藏 0 赞 0 分享

1、前言

写动态代理的代码涉及了一个非常重要的类 Proxy,通过Proxy的静态方法newProxyInstance才会动态创建代理对象。

2、newProxyInstance方法

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

三个参数分别表示: loader表示类加载器, interfaces表示代码要用来代理的接口 , h表示一个 InvocationHandler 对象,前面两个参数容易理解,

最后一个InvocationHandler是什么?

InvocationHandler是一个接口,官方文档解释说,每个代理的实例都有一个与之关联的 InvocationHandler 实现类,如果代理的方法被调用,那么代理便会通知和转发给内部的 InvocationHandler 实现类,由它决定处理。

public interface InvocationHandler {
  public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable;
}

InvocationHandler 内部只有一个 invoke() 方法,正是这个方法决定了怎么样处理代理传递过来的方法调用。其中参数proxy表示代理对象,method表示代理对象调用的方法,args表示调用的方法中的参数。所以Proxy动态产生的代理会调用InvocationHandler实现类,所以InvocationHandler才是实际执行者。

3、代码实例

//抽象主题
interface AbstractSubject
{
  void request();
}
//真实主题
class RealSubject implements AbstractSubject
{
  public void request()
  {
    System.out.println("访问真实主题方法...");
  }
}
//真实主题
class RealSubject1 implements AbstractSubject
{
  public void request()
  {
    System.out.println("访问真实主题方法1...");
  }
}
//动态代理类
class DynamicProxy implements InvocationHandler {
  private Object object;
  public DynamicProxy(Object object) {
    this.object = object;
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    before();
    Object result = method.invoke(object, args);
    after();
    return result;
  }
  private void before() {
    System.out.println("hello!");
  }
  private void after() {
    System.out.println("bye!");
  }
}
//测试类
public class TestDynamicProxyPattern {
  public static void main(String[] args) {
    AbstractSubject abstractSubject = new RealSubject();
    DynamicProxy dynamicProxy = new DynamicProxy(abstractSubject);
    Proxy.newProxyInstance(abstractSubject.getClass().getClassLoader(), abstractSubject.getClass().getInterfaces() , dynamicProxy);
    abstractProxy.request();
  }
}

上述动态代理只需要传入需要被代理类的对象(DynamicProxy dynamicProxy = new DynamicProxy(abstractSubject)),然后调用Proxy类的工厂方法newProxyInstance去动态地创建一个代理类,最后调用代理类的方法便实现了“增强功能”。使用了动态代理之后,无论有多少类多少方法需要增加逻辑,只需要在使用的时候将类对象传入得到代理对象,然后使用代理对象调用需要增强的方法即可。

所以这时候如果增加一个实现抽象主题的真是主题类,比如说叫做RealSubject1,这个时候只要只要把该类的对象传入动态代理类DynamicProxy中,通过接口又可以实现接口AbstractSubject的实现类。

这样来实现:

AbstractSubject abstractSubject1 = new RealSubject1();
DynamicProxy dynamicProxy = new DynamicProxy(abstractSubject1);

4、总结

1、区别于静态代理的生成代理类,动态代理的代理类通过 Proxy.newInstance() 方法生成。静态代理和动态代理的区别是在于要不要开发者自己定义 Proxy 类。

2、不管是静态代理还是动态代理,代理与被代理者都要实现接口,还是要是面向接口编程,目的都是增强现有功能。

3、动态代理通过 Proxy 动态生成 proxy class,但是它也指定了一个 InvocationHandler 的实现类。

4、动态代理也有缺陷,它要求需要代理的对象必须实现了某个接口,而且也不够灵活,动态代理会为接口中的声明的所有方法添加上相同的代理逻辑。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

JavaWeb项目部署到服务器详细步骤详解

这篇文章主要介绍了JavaWeb项目如何部署到服务器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

IDEA基于支付宝小程序搭建springboot项目的详细步骤

这篇文章主要介绍了IDEA基于支付宝小程序搭建springboot项目的详细步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解SpringBoot应用服务启动与安全终止

这篇文章主要介绍了SpringBoot应用服务启动与安全终止,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Spring Boot启动及退出加载项的方法

这篇文章主要介绍了Spring Boot启动及退出加载项的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Spring Data Jpa 自动生成表结构的方法示例

这篇文章主要介绍了Spring Data Jpa 自动生成表结构的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

IDEA中osgi的开发应用指南详解

这篇文章主要介绍了IDEA中osgi的开发应用指南详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解用maven将dubbo工程打成jar包运行

这篇文章主要介绍了详解用maven将dubbo工程打成jar包运行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

详解Java合并数组的两种实现方式

这篇文章主要介绍了Java合并数组的两种实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

使用Jenkins Pipeline自动化构建发布Java项目的方法

这篇文章主要介绍了使用Jenkins Pipeline自动化构建发布Java项目的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

使用Maven配置Spring的方法步骤

这篇文章主要介绍了使用Maven配置Spring的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多