《How does proxy do in CGLIB?》

Background


About 'CGLIB', we can get information form
http://cglib.sourceforge.net/

and in this article, we will use the asm framework, which website is: http://asm.ow2.org/index.html

Introduction


This proxy is not same as JDK1.2+, which main through CGLIB to do this proxy, accurately, CGLIB use their proxy to realize the method interceptor at runtime, and which work with filter make it more flexible.

(Tip:About create proxy in runtime, we can use two different techniques, CGLIB or JDK dynamic proxies, more see:http://danni505.blog.51cto.com/15547/346896)

Base of the CGLIB, which can construct an AOP of CGLib-based AOP,  which have support by spring framework.

Ok, now we have an four base opertaions for some datasource, but we need to control the delete operation just permit to daniel, and those base operations are some detail class, not show as interface, so what will you do if use proxy?

To solves the issue, here we use CGLIB proxy, the operation will contril by interceptor and the right person will control by filter, the code may be like this:

 

 



Source Code
 

package com.cglib; 

/** 
* Those are some base operation demo. 
*    
* @author daniel    cqyd505@gmail.com 
* @since 2010-07-08 11:25 
* 
*/ 
public class BaseOperations { 

  public void query() { 
    System.out.println("query"); 
  } 

  public void create() { 
    System.out.println("create"); 
  } 

  public void update() { 
    System.out.println("update"); 
  } 

  public void delete() { 
    System.out.println("delete"); 
  } 
} 

 
/** 
*    
*/ 
package com.cglib; 

import java.lang.reflect.Method; 

import net.sf.cglib.proxy.MethodInterceptor; 
import net.sf.cglib.proxy.MethodProxy; 

/** 
* Method interceptor, as you see, this is a Interceptor, which can do some job before you call some method, 
* and the key is which can be used in call back by cglib, it's real cool! 
*    
* @author daniel    cqyd505@gmail.com 
* @since 2010-07-09 09:23 
* 
*/ 
public class MyMethodInterceptor implements MethodInterceptor{ 
    
  private String name; 

  public String getName() { 
    return name; 
  } 

  public void setName(String name) { 
    this.name = name; 
  } 

  public MyMethodInterceptor(String name) { 
    this.name = name; 
  } 

  /** 
    * Here we will set our interceptor for some method. 
    * As you see the interceptor is just for daniel by name. 
    */ 
  @Override 
  public Object intercept(Object arg0, Method arg1, Object[] arg2, 
      MethodProxy arg3) throws Throwable { 
    //interceptor 
    if (this.name.equals("daniel")) { 
      return arg3.invokeSuper(arg0, arg2); 
    }else{ 
      System.out.println("Method interceptor say: haha, just daniel can do delete! you are have no permits to do this operation!"); 
                        return null; 
    } 
  } 

} 

 
package com.cglib; 

import java.lang.reflect.Method; 

import net.sf.cglib.proxy.CallbackFilter; 

/** 
* Interceptro filter, which mean this is a filter for interceptor, in other words, when app use the interceptor, filter 
* will be called first, so it's can use for abstract the logic or bussiness into the filter, mean while you can    
* set many interceptor and not case it use or not, the "CallBackFilter" will charge it, you just need to foucs 
* at what will you do in filter.    
*    
* @author daniel    cqyd505@gmail.com 
* @since 2010-07-09 10:30 
* 
*/ 
public class InterceptorFilter implements CallbackFilter{ 

  private String operationName; 
    
  @Override 
  public int accept(Method arg0) { 
    /* 
     * The accept logic 
     */ 
    if(arg0.getName().toString().equals(this.operationName)){ 
      /* 
        * if the method name is equals to the filter's , call the No:0 interceptor 
        */ 
      return 0; 
    }else{ 
      /* 
        * call No:1 interceptor 
        */ 
      return 1; 
    } 
  } 

  public InterceptorFilter(String name) { 
    this.operationName = name; 
  } 
    
} 

 
package com.cglib; 

import net.sf.cglib.proxy.Callback; 
import net.sf.cglib.proxy.Enhancer; 
import net.sf.cglib.proxy.NoOp; 

/** 
* This factory can set some interceptors into the callback of the class, not interface. 
*    
* @author daniel    cqyd505@gmail.com 
* @since 2010-07-09 09:25 
* 
*/ 
public class InterceptorFactory { 

  /** 
    * Here we will set the callback process by cglib's net.sf.cglib.proxy.Enhancer. 
    *    
    * @param interceptor 
    * @return BaseOperations 
    * @see net.sf.cglib.proxy.Enhancer 
    */ 
  public static BaseOperations getBtsOperationInstanceWithInterceptor(MyMethodInterceptor interceptor) { 
    /* 
     * This is a often and regular using of Enhancer. 
     */ 
    Enhancer enhancer = new Enhancer(); 
    enhancer.setSuperclass(BaseOperations.class); 
    /* 
     * setCallback just one interceptor 
     */ 
    enhancer.setCallback(interceptor); 
    /* 
     * set two interceptors into callback, which will used will see the filter's logic 
     */ 
    Callback[] backs =    new Callback[]{interceptor,NoOp.INSTANCE};     
    enhancer.setCallbacks(backs); 
    //set filter 
    enhancer.setCallbackFilter(new InterceptorFilter("delete")); 
    BaseOperations baseOpt = (BaseOperations) enhancer.create(); 
                return baseOpt; 
        } 
    
  /** 
    * Pay attention: 
    *         Enhancer.setCallback and setCallbacks, by check the enhancer's source codethe, we find the setCallback 
    * will call setCallbacks() to set the same "Callback[]", so if you use the setCallBack before setCallBacks    
    * in reslut, the Callback[] will fit to the last one. 
    *         Which Means, at here, ehancer have two interceptor in callback, not three!    
    */ 
    
} 

 
 
/** 
*    
*/ 
package com.cglib; 

/** 
* In this case, we will do the job by cglib, we have set some method interceptor for our operations, let's take a look! 
*    
* @author daniel    cqyd505@gmail.com 
* @since 2010-07-09 09:37 
* 
*/ 
public class CallInCase2 { 

  public static void main(String[] args) { 
    CallInCase2 c = new CallInCase2(); 
                c.doOperation(); 
        } 

  /** 
    * Do the base operations. 
    */ 
  private void doOperation() { 
    System.out.println("app run:"); 
    System.out.println("============================ console outting: ========================="); 
    //0.Create the interceptor 
    MyMethodInterceptor interceptor =    new MyMethodInterceptor("Tom"); //not ok 
    //1.Get handler by factory 
    BaseOperations basOptHandler = InterceptorFactory.getBtsOperationInstanceWithInterceptor(interceptor); 
    //2.Try do job 
    basOptHandler.create(); 
    basOptHandler.query(); 
    basOptHandler.update(); 
    basOptHandler.delete(); 
    //3.say BYEBYE 
    System.out.println("============================ app stop ========================="); 
  } 
    
} 

 



End


In fact, we just have used Enhancer, Callback, MethodInterceptor and CallbackFilter of CGLIB, it realize a proxy solution for us, and it's also be used widespread in some common use framework, if you take care about it.

(Tip:CGLIB, which API and document is so simple that I could find more using about she, so if you have any good using case, pls msn me by danni-505@hotmail.com)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值