LazyLoader: Even though the LazyLoader’s only method has the same method signature as FixedValue, the LazyLoader is fundamentally different to the FixedValue interceptor. The LazyLoader is actually supposed to return an instance of a subclass of the enhanced class. This instance is requested only when a method is called on the enhanced object and then stored for future invocations of the generated proxy. This makes sense if your object is expensive in its creation without knowing if the object will ever be used. Be aware that some constructor of the enhanced class must be called both for the proxy object and for the lazily loaded object. Thus, make sure that there is another cheap (maybe protected) constructor available or use an interface type for the proxy. You can choose the invoked constructed by supplying arguments to Enhancer#create(Object…).在被代理对象需要懒加载场景下非常有用,如果被代理对象加载完成,那么在以后的代理调用时会重复使用。
Dispatcher: The Dispatcher is like the LazyLoader but will be invoked on every method call without storing the loaded object. This allows to change the implementation of a class without changing the reference to it. Again, be aware that some constructor must be called for both the proxy and the generated objects.与net.sf.cglib.proxy.LazyLoader差不多,但每次调用代理方法时都会调用loadObject方法来加载被代理对象。
ProxyRefDispatcher: This class carries a reference to the proxy object it is invoked from in its signature. This allows for example to delegate method calls to another method of this proxy. Be aware that this can easily cause an endless loop and will always cause an endless loop if the same method is called from within ProxyRefDispatcher#loadObject(Object).与Dispatcher相同,但它的loadObject方法支持传入代理对象。
NoOp: The NoOp class does not what its name suggests. Instead, it delegates each method call to the enhanced class’s method implementation.
net.sf.cglib.proxy.CallbackFilter允许你在方法级别设置回调。
1 2 3 4 5 6 7 8 9 10
public class PersistenceServiceImpl implements PersistenceService {
public void save(long id, String data) { System.out.println(data + " has been saved successfully."); }
public class PersistenceServiceCallbackFilter implements CallbackFilter {
//callback index for save method private static final int SAVE = 0;
//callback index for load method private static final int LOAD = 1;
/** * Specify which callback to use for the method being invoked. * @method the method being invoked. * @return the callback index in the callback array for this method */ public int accept(Method method) { String name = method.getName(); if ("save".equals(name)) { return SAVE; } // for other methods, including the load method, use the // second callback return LOAD; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14
... Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(PersistenceServiceImpl.class);
CallbackFilter callbackFilter = new PersistenceServiceCallbackFilter(); enhancer.setCallbackFilter(callbackFilter);
Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types);