什么是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
慢一些,因为它需要创建类加载器并加载代理类。