Bean的加载
当解析完Bean的配置文件后,就要开始获取Bean,获取Bean则需要先加载,接下来就解析加载的过程;
People p =(People) bf.getBean("people");
1. getBean(String name)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
当我们跳转到还有该方法的类时,发现有很多类都有该方法,判断则是,根据具体具体的名字做分析;这里跳转的类为AbstractBeanFactory的getBean
2.doGetBean(...)
doGetBean的方法有150多行代码,大致执行的流程如下:
-
获取BeanName;
-
在缓存中寻找Bean是否以前加载过;
-
如果没有在缓存中,则去工厂中寻找Bean;
3.1进行类型检查或者创建对象;
3.2递归实例化依赖的bean;
3.3根据不同的scope创建不同的对象;
3.4检查需要的类型是否符合bean的实际类型;
3.transformedBeanName(name);
实际执行的代码为:
String FACTORY_BEAN_PREFIX = "&";
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
String beanName = name;
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
return beanName;
}
该方法的作用是:过滤掉factory的修饰符&,得到具体的beanName;
4.getSingleton(beanName);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}}}}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
首先是从singletonObjects中获取对象,如果没有,则从earlySingletonObjects中获取对象,如果还没有,则从工厂中获取对象,然后将获取的对象放入到earlySingletonObjects缓存中,以方便下次直接从earlySingletonObjects中获取,然后将对象从singletonFactories中删除,然后返回Object对象;
5.getObjectForBeanInstance(sharedInstance, name, beanName, null);
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
该方法所做的工作有:
对指定的name的工厂进行判断;
根据name来决定是否需要返回工厂实例而不是工厂的getObject方法;
尝试从缓存中加载bean;
将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition;
6.getObjectFromFactoryBean(factory, beanName, !synthetic)
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;}
else {
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);}}
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));}}
return (object != NULL_OBJECT ? object : null);}}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}}
return object;}}
该方法的作用有:
判断Bean是否是单例模式,如果是,则从缓存中加载对象,如果缓存中没有,则使用doGetObjectFromFactoryBean(factory, beanName);并将bean对象放入到缓存中,如果不是,则使用doGetObjectFromFactoryBean(factory, beanName);
7.doGetObjectFromFactoryBean(factory, beanName)
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
return factory.getObject();}
}, acc);}
catch (PrivilegedActionException pae) {
throw pae.getException();
}}
else {
object = factory.getObject();}}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
bef5ddsanName, "FactoryBean which is currently in creation returned null from getObject");
}
return object;
}
8.doGetBean
当Bean没有在缓存中时,接下来执行有:
isPrototypeCurrentlyInCreation(beanName)
该代码时将beanName进行标记,用来判断依赖循环。
BeanFactory parentBeanFactory = getParentBeanFactory();
从parentBeanFactory中检查Bean;
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
将GenericBeanDefinition转换为RootBeanDefinition;如果是子类bean,则同时合并父类的相关属性;
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
递归遍历需要实例化的依赖;
if (mbd.isSingleton()) {
......
return createBean(beanName, mbd, args);
......
根据配置文件中的scope的设置,开始具体的创建过程;
createBean(beanName, mbd, args);
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
根据Bean名解析BeanClass;
对Override属性进行标记以及验证;
应用初始化前的后处理器,解析bean初始化前的短路操作;
创建bean;
mbdToUse.prepareMethodOverrides();
prepareMethodOverride(mo);
==》
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
......
}
spring配置中没有override-method配置,spring配置中存在lookup-method和replace-method,而这两个配置的加载其实是统一存放在BeanDfinition中的methodOverrides属性里。这个属性就是操作这两个配置;
resolveBeforeInstantiation(beanName, mbdToUse);
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}}}
mbd.beforeInstantiationResolved = (bean != null);}
return bean;}
主要有两个方法,即实例化前的后处理器applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);实例化后的后处理器applyBeanPostProcessorsAfterInitialization(bean, beanName);
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);}
mbd.postProcessed = true;
}}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}}}}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
该方法比较复杂,我们分段介绍重要的:
如果是单例,则清除缓存,
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}
实例化Bean,将BeanDefinition转化为BeanWrapper;
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
createBeanInstance(beanName,mbd,args)
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
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());
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
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);
}
}
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
return instantiateBean(beanName, mbd);
}
该方法首先是解析class;
接下来判断类和方法的权限修饰;类必须是pulic,函数必须是public,注意这里已经不是单例;
如果工厂方法不为null,则使用工厂方法初始化策略;
如果工厂方法为空,则使用构造函数进行类的实例化;
当一个函数有多个构造函数时,这里需要同步确认使用的构造函数;
如果已经解析过则使用解析好的构造函数方法,接下来判断是否需要自动注入,需要的话则开始构造函数自动注入,不需要的话,则使用默认构造函数构造;(因为每次都根据参数及类型去判断使用哪个构造函数进行实例化,比较消耗性能,则使用缓存机制);
接下来根据参数解析构造函数,如果参数不为空,且有自动注入标识等,则使用构造函数自动注入,否则使用默认构造函数构造;
autowireConstructor(beanName, mbd, null, null);
调用内部的autowireConstructor(beanName, mbd, ctors, explicitArgs);
由于该方法比较长,则还是分块介绍重点:
该方法首先创建创建几个有关构造器,参数的变量;
接下来判断getBean方法在调用的时候,有没有显示的指定方法的参数,如果有,则直接使用,如果没有,从配置文件中解析,接下来锁定特定的构造器,然后从缓存中提取对象;如果缓存中存在,则进行参数转换,将参数转换为最终需要的,如果缓存中不存在,则接下来通过RootBeanDefinition对象中解析构造函数信息,解析构造函数中参数的值;
接下来给构造函数排序,遍历构造函数,判断参数,如果参数不为空,找到对应参数的构造函数,然后根据值构造对应参数类型的参数,获取参数名称探索器,获取指定构造函数的参数名称;根据名称和数据类型创建参数持有者;如果参数为空,则使用无参的构造函数;
接下来判断是否有不确定性的构造函数存在;如果有,并且代表最接近的匹配则选择作为构造函数;
然后将解析的构造函数加入缓存;
将构建的实例加入BeanWrapper中;
instantiateBean(beanName, mbd);
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
该方法即使用默认构造器实例化一个bean,主要是beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);该方法,
instantiate(mbd, beanName, parent)
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
if (bd.getMethodOverrides().isEmpty()) {
.....
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}});}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;}
......
return BeanUtils.instantiateClass(constructorToUse);}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
该方法首先判断(bd.getMethodOverrides().isEmpty(),即用户有没有使用replace或者lookup的配置方法,如果没有则直接使用反射的方式,如果使用了这两个特性,则需要使用CGLIB将这个特性对应的逻辑织入进去。
populateBean(beanName, mbd, instanceWrapper);
doCreateBean类下;
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
......
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
......
}
该方法主要有:
属性填充的判断;
根据注入类型(autowireByName|autowireByType),提取依赖的bean;
对属性获取完毕填充前对属性的再次处理;
将所有PropertyValues中的属性填充到BeanWrapper中;
《参考Spring源码深度解析》
如有问题,敬请指出,与君共勉