JDK Dynamic Proxy模式的简单范例

本文介绍JDK1.3引入的DynamicProxy机制,并通过一个简单案例演示如何使用该机制来拦截并修改方法调用。案例包括定义接口、实现类及自定义InvocationHandler。
JDK Dynamic Proxy模式的简单范例          Spring aop用这个实现
      在JDK1.3版本中引入了Dynamic Proxy的代理机制,通过实现java.lang.reflect.InvocationHandler接口,可以实现拦截需要改写的方法。下面是一个简单范例。
      有下面一个接口TestInterface和它的一个实现TestImpl:

package sample.proxy;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: </p>
 *
 * @author George Hill
 * @version 1.0
 
*/


public   interface  TestInterface  {

  
public String print();

}


package sample.proxy;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: </p>
 *
 * @author George Hill
 * @version 1.0
 
*/


public   class  TestImpl implements TestInterface  {
  
  
public String print() {
    
return "Hello, it's from TestImpl class";
  }

  
}


      下面拦截print方法,调用自己的实现,这需要实现java.lang.reflect.InvocationHandler接口。

package sample.proxy;

import java.lang.reflect.
* ;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: </p>
 *
 * @author George Hill
 * @version 1.0
 
*/


public   class  TestHandler implements InvocationHandler  {
  
  TestInterface test;
  
  
/**
   * 将动态代理绑定到指定的TestInterface
   * @param test TestInterface
   * @return TestInterface 绑定代理后的TestInterface
   
*/

  
public TestInterface bind(TestInterface test) {
    
this.test = test;
    
    TestInterface proxyTest 
= (TestInterface) Proxy.newProxyInstance(
      test.getClass().getClassLoader(), test.getClass().getInterfaces(), 
this);
    
    
return proxyTest;
  }

  
  
/**
   * 方法调用拦截器,拦截print方法
   * @param proxy Object
   * @param method Method
   * @param args Object[]
   * @return Object
   * @throws Throwable
   
*/

  
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
// 如果调用的是print方法,则替换掉
    if ("print".equals(method.getName())) {
      
return "HaHa, It's come from TestHandler";
    }
 else {
      
return method.invoke(this.test, args);
    }

  }

  
}


      下面是测试用例:

package sample.test;

import junit.framework.
* ;

import sample.proxy.
* ;

/**
 * <p>Title: </p> 
 * 
 * <p>Description: </p> 
 * 
 * <p>Copyright: Copyright (c) 2005</p> 
 * 
 * <p>Company: </p>
 * 
 * @author George Hill
 * @version 1.0
 
*/


public   class  TestDynamicProxy extends TestCase  {
  
  
private TestInterface test = null;

  
protected void setUp() throws Exception {
    super.setUp();
    TestHandler handler 
= new TestHandler();
    
// 用handler去生成实例
    test = handler.bind(new TestImpl());
  }


  
protected void tearDown() throws Exception {
    test 
= null;
    super.tearDown();
  }


  
public void testPrint() {
    System.
out.println(test.print());
  }


}


      运行测试用例,可以看到输出的是“HaHa, It's come from TestHandler”。  
17:21:55.658 [main] WARN net.openhft.posix.internal.PosixAPIHolder -- Unable to load JNRPosixAPI com.oracle.svm.core.jdk.UnsupportedFeatureError: Proxy class defined by interfaces [interface net.openhft.posix.internal.jnr.WinJNRPosixInterface, interface jnr.ffi.provider.LoadedLibrary] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options. 17:21:55.747 [main] WARN net.openhft.affinity.Affinity -- Windows JNA-based affinity not usable because it failed to load! Reason: com.oracle.svm.core.jdk.UnsupportedFeatureError: Proxy class defined by interfaces [interface net.openhft.affinity.impl.WindowsJNAAffinity$CLibrary] not found. Generating proxy classes at runtime is not supported. Proxy classes need to be defined at image build time by specifying the list of interfaces that they implement. To define proxy classes use -H:DynamicProxyConfigurationFiles=<comma-separated-config-files> and -H:DynamicProxyConfigurationResources=<comma-separated-config-resources> options.17:21:55.748 [main] INFO net.openhft.affinity.Affinity -- Using dummy affinity control implementation 17:21:55.752 [main] ERROR net.openhft.chronicle.core.Jvm -- Chronicle products require command line arguments to be provided for Java 11 and above. See https://chronicle.software/chronicle-support-java-17 Exception in thread "main" java.lang.ExceptionInInitializerError 我编译后启动exe程序报错
09-30
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值