分享

小格格恭候您的光临!: 昨天一晚上学的新东东-cglib

 ShangShujie 2007-04-12

Cglib

Cglib is a powerful, high performance and quality Code Generation Library, It is used to extend JAVA classes and implements interfaces at runtime. It is a high level API to generate and transform JAVA byte code. It is used by AOP(Aspect Oriented Programming), testing, data access frameworks to generate dynamic proxy objects and intercept field access. Especially for a small quantity of code.

It is getting more and more popular recent years. Several open source projects use cglib and used by cglib, such as Hibernate,XORM, The Byte Code Engineering Library, The Java Class File Editor, Voruta,Nanning  Aspects,Spring, ASM and so on.

 

The principle of cglib is using Enhancer to generate a subclass of a previous class. And then with a well configuration of callback so that when the methods of the previous class are called they will be intercepted and transformed into the proxy method Intercept() to implement the interface of MethodInterceptor:

public Object intercept(Object o,Method method,Object[] args,MethodProxy proxy).

In the method of intercept(), you can execute ‘Object result=proxy.invokeSuper(o,args)‘ instead of the previous method and you can also change the parameters before or after your execution,so you will complete your function.

 

Take the following instance for example with essential annotate.

public class Beans implements MethodInterceptor {

    private PropertyChangeSupport propertySupport;

    public void addPropertyChangeListener(PropertyChangeListener listener) {         

          propertySupport.addPropertyChangeListener(listener);     //config the listener of //adding a property  

      }

      public void removePropertyChangeListener(PropertyChangeListener listener) {

          propertySupport.removePropertyChangeListener(listener);  //config the listener of //removing a property

     }

      public static  Object newInstance( Class clazz ){       //return a new instance of //Enhancer object

        try{

            Beans interceptor = new Beans(); //define a intercepter,and it is a class of Beans

           Enhancer e = new Enhancer();                     //generate an Enhancer

           e.setSuperclass(clazz);       //set the super class, and it is the previous class

           e.setCallback(interceptor);  //set the callback of interceptor for invoking the proxy’s //Intercept() method  

              Object bean = e.create(); //create an Enhancer object

              interceptor.propertySupport = new PropertyChangeSupport( bean );

            return bean;

        }catch( Throwable e ){

              e.printStackTrace();

             throw new Error(e.getMessage());

          }         

      }     

      static final Class C[] = new Class[0];

     static final Object emptyArgs [] = new Object[0]; 

      public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {               //default method of intercepting, an object which is the                                         //result of invoking the proxy’s method will be returned

         Object retValFromSuper = null;

         try {

             if (!Modifier.isAbstract(method.getModifiers())) {

            retValFromSuper = proxy.invokeSuper(obj, args); //if there is something modified // in the method, the method of the proxy will be invoked

             }

         } finally {

             String name = method.getName();

              if( name.equals("addPropertyChangeListener")) {

                 addPropertyChangeListener((PropertyChangeListener)args[0]);

              }else if ( name.equals( "removePropertyChangeListener" ) ){

                 removePropertyChangeListener((PropertyChangeListener)args[0]);

             }

              if( name.startsWith("set") &&

                  args.length == 1 &&

                 method.getReturnType() == Void.TYPE ){           

                  char propName[] = name.substring("set".length()).toCharArray();            

                 propName[0] = Character.toLowerCase( propName[0] );

                 propertySupport.firePropertyChange( new String( propName ) , null , args[0]);             

             }

         }

         return retValFromSuper;

      }    

      public static void main( String args[] ){

          Bean  bean =  (Bean)newInstance( Bean.class );         

          bean.addPropertyChangeListener(

         new PropertyChangeListener(){

             public void propertyChange(PropertyChangeEvent evt){

                 System.out.println(evt);

            }

 }

);

bean.setSampleProperty("TEST");        

    }     

 }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多