在前面已经封装好BeanDefinition之后,那么接下来就根据指定的BeanDefinition通过反射生成指定的对象。
1、根据目标对象确定实例的产生方式:JDK或者CGLIB。有Override方法目标对象,使用CGLIB方式实例化具体的对象。
// SimpleInstantiationStrategy
// 具体的bean实例化
// JDK或者CGLIB
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// 如果没有覆盖,不要用CGLIB覆盖类。
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
// 获取对象的构造器或许工厂方法
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
// 获取的构造器或许工厂方法失败
if (constructorToUse == null) {
// 获取对应类的class对象 采用JDK反射机制
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
// 接口无法实例
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
// 匿名内部类 通过反射获取默认构造方法
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
// 通过待实例化bean的Class对象获取申明的构造器
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 调用BeanUtils的静态方法instantiateClass
// 通过constructor.newInstance(args);来实例化对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 使用CGLIB来实例化对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
在上面方法的结尾调用instantiateWithMethodInjection(bd, beanName, owner);方法来通过CGlib方式创建对象,通过代码跟踪,发现该方法的具体实现是在CglibSubclassingInstantiationStrategy中的instantiate(Constructor<?>ctor, Object... args)里面实现的,代码如下:
// CglibSubclassingInstantiationStrategy
// 创建一个实现所需查找的动态生成子类的新实例。
// 参数ctor是构造函数。
// 如果这是空的,则使用无参数构造函数(无参数化或设置器注入)
public Object instantiate(Constructor<?> ctor, Object... args) {
// 使用CGLIB为所提供的bean定义创建一个增强的bean类的子类。
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
// 构造方法为null 使用默认无参构造器
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
// 获取增强的子类构造函数
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
// 获取增强的子类构造器实例化的对象
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// 直接在实例上而不是在增强类中(通过增强器)设置回调,
// 以避免内存泄漏。
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
通过JDK和CGlib两种方式,实现了根据BeanDefinition来生成一个指定的类。
至于为什么要用两种不同的方式生成目标实例,原因很简单:JDK是针对接口生成代理对象,而CGlib则是生成目标对象的子类的实例化对象,这个实例化对象的运行时生成的,而且覆盖了父类所有的方法。