上篇提到bean的生成就是在AbstractAutowireCapableBeanFactory#doCreateBean方法中:
- createBeanInstance(beanName, mbd, args),实例化;
- populateBean(beanName, mbd, instanceWrapper),填充属性;
- initializeBean(beanName, exposedObject, mbd),初始化;
这篇就来看下实例化的具体过程。
- AbstractAutowireCapableBeanFactory#createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 确保Class文件有被加载
Class> beanClass = resolveBeanClass(mbd, beanName);
// 校验权限,权限不对则直接抛出异常
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// 工厂方法实例化bean,也就是我们配置的factory-method这个属性
// 会调用我们配置的factory-method方法来实例化这个bean
Supplier> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 分支一:构造方法注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 分支二:无参构造方法,先看这个,这个比较简单
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_ConSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
这个方法主要是做了一些校验,然后处理了我们配置的工厂方法,简单来说就是我们可以通过factory-method属性来配置一个产生bean的工厂方法,在方法instantiateUsingFactoryMethod中,调用这个工厂方法来实例化相应的bean,如果不是这样方式的话,那就会调用构造方法来实例化bean。
- AbstractAutowireCapableBeanFactory#instantiateBean
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction
这个方法没什么好说的,接着看吧。
- SimpleInstantiationStrategy#instantiation
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 如果没有方法覆盖就用Java的反射进行实例化,否则用cglib
if (!bd.hasMethodOverrides()) {
Constructor> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
// 获得Class对象
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(
(PrivilegedExceptionAction>) clazz::getDeclaredConstructor);
}
else {
// 获取构造方法
constructorToUse = clazz.getDeclaredConstructor();
}
// 属性设置,这个属性很多地方都会用到,当这个Bean第二次实例化的时候就直接用这个属性了
// 在createBeanInstance方法里都有用到
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 就是反射调用了,就不看了
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// CGLIB,因为Java反射是不支持生成子类的bean的,所以如果存在方法覆盖时,只能用CGLIB来生成子类的bean
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
在这个方法中可以看到,实例化本质就是用了反射来生成bean对象,通过class对象来获取构造方法,然后调用newInstance方法来创建一个对象,实例化一个bean。而如果有方法覆盖的话,还需要用到CGLIB。
到这里,整个实例化bean的过程就看完了,只要抓住它的本质就是根据BeanDefinition信息来生成对应的bean就比较容易了:
- BeanDefinition对象获取class对象;
- class对象获取构造方法;
- 构造方法调用newInstance方法来创建对象。



