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"); } } |
|
来自: ShangShujie > 《java》