cglib使用

cglib,全称是Code Generation Library,它可以用来动态继承Java类或者实现接口,很多知名的开源项目中用到了它,譬如Hibernate,Spring之类用它来实现动态代理。

增强一个已有类
public class MyClass {

 public void method() {
  System.out.println("MyClass.method()");
 }
}
import java.lang.reflect.Method;

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

public class Main {

 public static void main(String[] args) {

  Enhancer enhancer = new Enhancer();

  enhancer.setSuperclass(MyClass.class);
  enhancer.setCallback( new MethodInterceptorImpl() );


  MyClass my = (MyClass)enhancer.create();

  my.method();
 }

 private static class MethodInterceptorImpl implements MethodInterceptor {
  
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

   System.out.println(method);

   proxy.invokeSuper(obj, args);

   return null;
  }
 }
}
执行结果:
public void cglib_test.MyClass.method()
MyClass.method()

 

 


使用CallbackFilter
public class MyClass {

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

 public void method2() {
  System.out.println("MyClass.method2()");
 }
}
import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.NoOp;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;


public class Main {

 public static void main(String[] args) {

  Callback[] callbacks =
   new Callback[] { new MethodInterceptorImpl(),  NoOp.INSTANCE };

  Enhancer enhancer = new Enhancer();

  enhancer.setSuperclass(MyClass.class);
  enhancer.setCallbacks( callbacks );
  enhancer.setCallbackFilter( new CallbackFilterImpl() );


  MyClass my = (MyClass)enhancer.create();

  my.method();
  my.method2();
 }

 private static class CallbackFilterImpl implements CallbackFilter {

  public int accept(Method method) {

   if ( method.getName().equals("method2") ) {
    return 1;

   } else {
    return 0;
   }
  }
 }

 private static class MethodInterceptorImpl implements MethodInterceptor {
  
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

   System.out.println(method);

   return proxy.invokeSuper(obj, args);
  }
 }
}
执行结果:
public void cglib_test.MyClass.method()
MyClass.method()
MyClass.method2()

 

 


使用Mixin
public interface MyInterfaceA {

 public void methodA();
}

public interface  MyInterfaceB {
 public void methodB();
}

public class MyInterfaceAImpl implements MyInterfaceA {

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

public class MyInterfaceBImpl implements MyInterfaceB {

 public void methodB() {
  System.out.println("MyInterfaceBImpl.methodB()");
 }
}
import net.sf.cglib.proxy.Mixin;

public class Main {

 public static void main(String[] args) {

  Class[] interfaces =
   new Class[] { MyInterfaceA.class, MyInterfaceB.class };
  
  Object[] delegates =
   new Object[] { new MyInterfaceAImpl(), new MyInterfaceBImpl() };
   
  
  Object obj = Mixin.create(interfaces, delegates);


  MyInterfaceA myA = (MyInterfaceA)obj;
  myA.methodA();


  MyInterfaceB myB = (MyInterfaceB)obj;
  myB.methodB();
 }
}
执行结果:
MyInterfaceAImpl.methodA()
MyInterfaceBImpl.methodB() 

 

 

在多层结构体系中,我们经常要大量的在对象之间拷贝属性,使用jakarta的commons BeanUtils工具类是我们省去了重复的set,get体力活,但带来之的却是性能的损失,BeanUtils用反射来完成功能,当然在对象的数量相对较少时,这点性能是可以忽略的,但当对象数量很大时,不得不考虑能否采用更好的解决方案.   Cglib提供了类似的功能,以字节码增强的形式.我小测了二者之间的性能.大量Bean的拷贝,cglib比beanutils性能好了一个数量级,

/* * Created on 2005-5-1 * */

package org.jjyao.cglib;

import net.sf.cglib.beans.BeanCopier;

import org.apache.commons.beanutils.BeanUtils;

import org.apache.log4j.Logger;

/**

 * FinalCheat

 * 

 * @author jjyao 2005-5-1

 */

public class PropertyCopyTest {   

    static final private Logger logger = Logger.getLogger(PropertyCopyTest.class);   

    public static class Other {       

        String userName;       

  String password;       

        int age;       

        String dateTime;       

        /**        

         * @return Returns the age.        

         */       

        public int getAge() {           

                return age;       

        }       

        /**        

         * @param age        

         *            The age to set.        

         */       

        public void setAge(int age) {           

            this.age = age;       

        }       

        /**        

         * @return Returns the dateTime.        

         */       

        public String getDateTime() {           

            return dateTime;       

        }       

        /**        

         * @param dateTime        

         *            The dateTime to set.        

         */       

         public void setDateTime(String dateTime) {           

             this.dateTime = dateTime;       

         }       

         /**        

          * @return Returns the password.        

          */       

        public String getPassword() {           

            return password;       

        }       

        /**        

         * @param password        

         *            The password to set.        

         */       

         public void setPassword(String password) {           

             this.password = password;       

         }       

         /**        

          * @return Returns the userName.        

          */       

         public String getUserName() {           

             return userName;       

         }       

         /**        

          * @param userName        

          *            The userName to set.        

         */       

         public void setUserName(String userName) {           

             this.userName = userName;       

         }       

         public String toString() {           

            StringBuffer sb = new StringBuffer();           

            sb.append("Other[");           

   sb.append("UserName=");           

   sb.append(this.userName);           

   sb.append(",");           

   sb.append("Password=");           

   sb.append(this.password);           

   sb.append(",");           

   sb.append("Age=");           

   sb.append(this.age);           

   sb.append(",");           

   sb.append("DateTime=");           

   sb.append(this.dateTime);           

   sb.append("]");           

   return sb.toString();       

        }   

 }   

    public static class Myth {       

  String userName;       

  String password;       

  int age;       

  long dateTime;       

  /**        

   * @return Returns the dateTime.        

   */       

  public long getDateTime() {           

   return dateTime;       

  }       

  /**        

   * @param dateTime        

   *            The dateTime to set.        

   */       

  public void setDateTime(long dateTime) {           

   this.dateTime = dateTime;       

  }       

  /**        

   * @return Returns the age.        

   */       

  public int getAge() {           

   return age;       

  }       

  /**        

   * @param age        

   *            The age to set.        

   */       

  public void setAge(int age) {           

   this.age = age;       

  }       

  /**        

   * @return Returns the password.        

   */       

  public String getPassword() {           

   return password;       

  }       

  /**        

   * @param password        

   *            The password to set.        

   */       

  public void setPassword(String password) {           

   this.password = password;       

  }       

   /**        

   * @return Returns the userName.        

   */       

  public String getUserName() {              

   return userName;       

  }       

  /**        

   * @param userName        

   *            The userName to set.        

   */       

  public void setUserName(String userName) {           

   this.userName = userName;       

  }   

 }   

 private Myth init() {       

  Myth myth = new Myth();       

  myth.setUserName("jjyao");       

  myth.setPassword("1111");       

  myth.setAge(24);       

     myth.setDateTime(System.currentTimeMillis());       

  return myth;   

 }   

 public static void main(String[] args) throws Exception {       

  String argument = null;       

  if (args != null && args.length > 0) {           

   argument = args[0];       

  } else {           

   throw new IllegalArgumentException("invalid args ");       

  }       

  Other other = new Other();       

  Myth myth = new PropertyCopyTest().init();       

  if ("cglib".equals(argument)) {           

   BeanCopier copier = BeanCopier.create(Myth.class, Other.class, false);           

   long beginTime = System.currentTimeMillis();           

   for (int i = 0; i < 1000000; i++) {               

    copier.copy(myth, other, null);           

   }           

   logger.info("" + other);           

   logger.info(" Use Cglib,It costs time : " + (System.currentTimeMillis() - beginTime));       

  } else if ("beanUtil".equals(argument)) {           

   long beginTime = System.currentTimeMillis();           

   for (int i = 0; i < 100000; i++) {               

    BeanUtils.copyProperties(other, myth);           

   }           

   logger.info("" + other);           

   logger.info(" Use BeanUtils,It costs time : "                    + (System.currentTimeMillis() - beginTime));       

  }   

 }

}

java PropertyCopyTest  cglib


15:37:53,140  INFO PropertyCopyTest:214 -  Use Cglib,It costs time : 31

====================

java PropertyCopyTest  beanUtil

15:39:15,046  INFO PropertyCopyTest:224 -  Use BeanUtils,It costs time : 3546

posted on 2010-11-24 20:40  aurawing  阅读(3421)  评论(0编辑  收藏  举报