java动态代理机制和反射机制间的联系


代理设计模式是为其他对象提供一种代理以控制对这个对象的访问。

典型的动态代理创建对象过程可分为以下四个步骤:
1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);
2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});
3、通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4、通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入
Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
为了简化对象创建过程,Proxy类中的newInstance方法封装了2~4,只需两步即可完成代理对象的创建。
生成的ProxySubject继承Proxy类实现Subject接口,实现的Subject的方法实际调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的的方法(Object result=method.invoke(proxied,args))

代理模式示例小demo:

复制代码
public interface Subject   
{   
  public void doSomething();   
}   
public class RealSubject implements Subject   
{   
  public void doSomething()   
  {   
    System.out.println( "call doSomething()" );   
  }   
}   
public class ProxyHandler implements InvocationHandler   
{   
  private Object proxied;   
     
  public ProxyHandler( Object proxied )   
  {   
    this.proxied = proxied;   
  }   
     
  public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable   
  {   
    //在转调具体目标对象之前,可以执行一些功能处理

    //转调具体目标对象的方法
    return method.invoke( proxied, args);  
    
    //在转调具体目标对象之后,可以执行一些功能处理
  }    
} 
复制代码
复制代码
import java.lang.reflect.InvocationHandler;   
import java.lang.reflect.Method;   
import java.lang.reflect.Proxy;   
import sun.misc.ProxyGenerator;   
import java.io.*;   
public class DynamicProxy   
{   
  public static void main( String args[] )   
  {   
    RealSubject real = new RealSubject();   
    Subject proxySubject = (Subject)Proxy.newProxyInstance(Subject.class.getClassLoader(), 
     new Class[]{Subject.class}, 
     new ProxyHandler(real));
         
    proxySubject.doSomething();
   
    //write proxySubject class binary data to file   
    createProxyClassFile();   
  }   
     
  public static void createProxyClassFile()   
  {   
    String name = "ProxySubject";   
    byte[] data = ProxyGenerator.generateProxyClass( name, new Class[] { Subject.class } );   
    try  
    {   
      FileOutputStream out = new FileOutputStream( name + ".class" );   
      out.write( data );   
      out.close();   
    }   
    catch( Exception e )   
    {   
      e.printStackTrace();   
    }   
  }   
}  
复制代码

动态代理示例小demo: 
1、BookFacade.java 

  1. package net.battier.dao;  
  2.   
  3. public interface BookFacade {  
  4.     public void addBook();  
  5. }  

 

2、BookFacadeImpl.java 

  1. package net.battier.dao.impl;  
  2.   
  3. import net.battier.dao.BookFacade;  
  4.   
  5. public class BookFacadeImpl implements BookFacade {  
  6.   
  7.     @Override  
  8.     public void addBook() {  
  9.         System.out.println("增加图书方法。。。");  
  10.     }  
  11.   
  12. }  
  13.   
  14. 、BookFacadeProxy.java  
  15.   
  16. package net.battier.proxy;  
  17.   
  18. import java.lang.reflect.InvocationHandler;  
  19. import java.lang.reflect.Method;  
  20. import java.lang.reflect.Proxy;  
  21.   
  22. /** 
  23.  * JDK动态代理代理类 
  24.  *  
  25.  * @author student 
  26.  *  
  27.  */  
  28. public class BookFacadeProxy implements InvocationHandler {  
  29.     private Object target;  
  30.     /** 
  31.      * 绑定委托对象并返回一个代理类 
  32.      * @param target 
  33.      * @return 
  34.      */  
  35.     public Object bind(Object target) {  
  36.         this.target = target;  
  37.         //取得代理对象  
  38.         return Proxy.newProxyInstance(target.getClass().getClassLoader(),  
  39.                 target.getClass().getInterfaces(), this);   //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)  
  40.     }  
  41.   
  42.     @Override  
  43.     /** 
  44.      * 调用方法 
  45.      */  
  46.     public Object invoke(Object proxy, Method method, Object[] args)  
  47.             throws Throwable {  
  48.         Object result=null;  
  49.         System.out.println("事物开始");  
  50.         //执行方法  
  51.         result=method.invoke(target, args);  
  52.         System.out.println("事物结束");  
  53.         return result;  
  54.     }  
  55.   
  56. }  

 

3、TestProxy.java 

  1. package net.battier.test;  
  2.   
  3. import net.battier.dao.BookFacade;  
  4. import net.battier.dao.impl.BookFacadeImpl;  
  5. import net.battier.proxy.BookFacadeProxy;  
  6.   
  7. public class TestProxy {  
  8.   
  9.     public static void main(String[] args) {  
  10.         BookFacadeProxy proxy = new BookFacadeProxy();  
  11.         BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());  
  12.         bookProxy.addBook();  
  13.     }  
  14.   
  15. }  
至于反射请查看前篇日志《且谈谈我对Java反射的理解》,相信对比两篇文章,朋友们对反射和代理一定会有更深刻的认知,好了,就写到这里吧!



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值