什么是CGLIB实例化策略?
CGLIB实例化策略是Spring中用来控制CGLIB创建代理对象的策略。在Spring中,CGLIB通过一个名为Enhancer的类来创建代理对象。Enhancer会为被代理类创建子类,并在子类中插入一些拦截器逻辑。CGLIB创建代理对象的过程是通过一个名为InstanceStrategy的接口来控制的。InstanceStrategy接口定义了创建代理对象的策略,它有两个实现类:SimpleInstanceStrategy和AbstractClassGenerator。
SimpleInstanceStrategy实例化策略
SimpleInstanceStrategy是默认的实例化策略,它会为每个被代理对象创建一个新的代理对象。这意味着,如果你有10个被代理对象,那么Spring会创建10个代理对象。SimpleInstanceStrategy的实现很简单,它只是直接调用Enhancer的create()方法来创建代理对象。以下是SimpleInstanceStrategy的代码:
public class SimpleInstanceStrategy implements InstanceStrategy {public Object newInstance(Class type, Callback[] callbacks, Object[] args, CallbackFilter filter) throws InstantiationException, IllegalAccessException {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(type);enhancer.setCallbacks(callbacks);enhancer.setCallbackFilter(filter);return enhancer.create(args);}
}
AbstractClassGenerator实例化策略
AbstractClassGenerator是一个更高级的实例化策略,它可以为多个被代理对象重用同一个代理类。这意味着,如果你有10个被代理对象,那么Spring可能只需要创建一个代理类,然后为每个被代理对象创建一个代理对象。AbstractClassGenerator的实现比SimpleInstanceStrategy复杂一些,它会为每个被代理类创建一个类加载器,然后使用类加载器来加载代理类。以下是AbstractClassGenerator的代码:
public abstract class AbstractClassGenerator implements InstanceStrategy {protected ClassLoader classLoader;protected ClassGenerator classGenerator;protected Class generatedClass;public AbstractClassGenerator(ClassLoader classLoader) {this.classLoader = classLoader;}public Object newInstance(Class type, Callback[] callbacks, Object[] args, CallbackFilter filter) throws InstantiationException, IllegalAccessException {if (generatedClass == null) {classGenerator = new ClassGenerator(classLoader);classGenerator.setInterfaces(type.getInterfaces());classGenerator.setSuperclass(type);classGenerator.setNamePrefix(type.getName());classGenerator.setUseCache(false);classGenerator.setUseFactory(false);classGenerator.setCallbacks(callbacks);classGenerator.setCallbackFilter(filter);generatedClass = classGenerator.createClass();}return generatedClass.newInstance();}
}
如何选择实例化策略?
在Spring中,默认使用的是SimpleInstanceStrategy,它会为每个被代理对象创建一个新的代理对象。但是,如果你想为多个被代理对象重用同一个代理类,那么可以使用AbstractClassGenerator。需要注意的是,使用AbstractClassGenerator会比使用SimpleInstanceStrategy慢一些,因为它需要创建类加载器并加载代理类。但是,如果你有很多被代理对象,那么使用AbstractClassGenerator可以节省内存,因为它可以重用同一个代理类。
总之,在Spring中,CGLIB创建代理对象的过程是通过InstanceStrategy接口来控制的。默认的实例化策略是SimpleInstanceStrategy,它会为每个被代理对象创建一个新的代理对象。如果你想为多个被代理对象重用同一个代理类,那么可以使用AbstractClassGenerator。但是,需要注意的是,使用AbstractClassGenerator会比使用SimpleInstanceStrategy慢一些,因为它需要创建类加载器并加载代理类。