Bean的实例化
结构器的抉择
SimpleInstantiationStrategy
Bean实例化有两种策略,一种是CGLIB,另一种是通过
BeanUtil
,即用JVM反射生成对象。
如果Bean中有@LookUp
注解,或者xml中指定了lookup-method
,那么就会采纳CGLIB来实例化对象,因为须要重写@LookUp
标记的办法,这种状况下很容易想到应用代理,应用代理,被代理类又不需实现接口,无疑CGLB形式适合。
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
//获取无参结构器去实例化Bean
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 通过JVM反射性能生成实例化对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 通过CGLIB来生成实例化对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
发表回复