Spring中bean的实例化的总的入口都是getBean方法
具体的实现是在AbstractBeanFactory中。
getBean->doGetBean,最终的逻辑是在doGetBean中
doGetBean的大体逻辑归纳如下:
转换bean名字
if(原生bean实例已经实例化){
判断该bean是否是FactoryBean,若是,则获取FactoryBean创建的bean。若FactoryBean是单例,则将创建的bean缓存起来。
}else{
if(bean存在于父容器中){
从父容器中获取bean实例
}else{
获取bean的定义信息BeanDefinition
先实例化依赖的bean
if(bean配置为单例){
先创建bean的实例
然后判断bean是否是FactoryBean,若是,则获取FactoryBean创建的bean,若FactoryBean是单例,则将创建的bean缓存起来。
}else if(bean配置为原型){
实例化bean的前置准备(默认实现中,是把当前beanName加入到prototypesCurrentlyInCreation集合中,用于检查循环依赖的问题)
创建bean的实例
实例化的后置操作(默认实现中,是把当前beanName从prototypesCurrentlyInCreation集合中删除。)
然后判断bean是否是FactoryBean,若是,则获取FactoryBean创建的bean,若FactoryBean是单例,则将创建的bean缓存起来。
}else{
获取bean的scope
采用原型bean创建的过程创建bean实例
将bean加入到scope中
然后判断bean是否是FactoryBean,若是,则获取FactoryBean创建的bean,若FactoryBean是单例,则将创建的bean缓存起来。
}
}
检查bean的类型与传入参数指定类型是否一致
根据上面的逻辑可以看出,bean的实例化过程中主要是按照三种scope域进行实例化。
下面根据上面的大体逻辑把getBean分成以下几段独立逻辑分别分析。
final String beanName = transformedBeanName(name);
bean名字转换:
1.首先去除FactoryBean对应的name的前缀。这里FacotryBean实例的前缀为&,应该注意的是,FacotryBean自身是可以嵌套的,即某个FactoryBean可以由其他FactoryBean创建。
2.然后若name为别名,则获取别名对应的正真的beanName。别名的管理由SimpleAliasRegistry负责,其中提供了一个aliasMap,存储的结构为[alias,beanName]
1. getSingleton(),从缓存singletonObjects中获取已经实例化的bean,如果bean已经被实例化,则执行下面的逻辑:
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
2. 上面这段代码的主要逻辑是在getObjectForBeanInstance中,这个方法也是每个bean在实例化都会执行的一段逻辑,该方法的大体逻辑是:判断传入的bean实例是否是FactoryBean,若不是,则直接返回该实例,否则则用FactroyBean创建对应bean的实例。在后面会讲到FactoryBean实际上就是AOP和IOC容器的一个接入点。
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;
这里,
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
1. isPrototypeCurrentlyInCreation方法是用于循环依赖检测,spring在实例化prototype类型的bean之前,会把bean的名字加入到“正在创建的缓存”中,若bean1在创建过程依赖bean2,而bean2创建过程中同时又依赖bean1,则直接抛出异常。
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (int i = 0; i < dependsOn.length; i++) {
String dependsOnBean = dependsOn[i];
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
这里是三类scope实例化前共有的逻辑。
if(mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
1.getSingleton()是一个包含回调接口的方法,定义了创建原生bean实例的模板过程,正在的实例化bean的逻辑由外部传入的ObjectFactory接口实现。
beforeSingletonCreation()
try{
objectFactory.getObject();
}catch(Exception e){
}finally{
afterSingletonCreation
}
addSingleton();
真正的创建过程的过程在AbstractAutowireCapableBeanFactory.createBean方法中。createBean方法中会产生bean实例,具体过程后面深入分析。
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
原型实例化的过程实际上与单例实例化的过程类似,
String scopeName = mbd.getScope();
final Scope scope = (Scope) this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; " +
"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
如果没有指定,则从scope中创建bean。
public Object get(String name, ObjectFactory objectFactory) {
RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
Object scopedObject = attributes.getAttribute(name, getScope());
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
attributes.setAttribute(name, scopedObject, getScope());
}
return scopedObject;
}
如果request中已经缓存了实例,直接返回,否则利用objectFactory创建bean实例,并且保存到attribute中。
resolveBeanClass(mbd, beanName);
// Prepare method overrides.
try {
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
1. resolveBeanClass()加载bean指定的class.
另一种是replace-method方式,但是需要实现MethodReplacer接口
String
3. resolveBeforeInstantiation()调用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法处理,扩展点,用于返回bean的代理对象,干涉bean的实例化。从代码中可以看到,resolveBeforeInstantiation如果创建了bean,则直接返回该实例。
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
这里需要注意的是initBeanWrapper,该方法会拷贝一份容器中注册的PropertyEditor,用于属性类型转换。
第二种方式:
3. 得到factory-method中方法的参数值
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() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
从代码逻辑可以看出,这里会把beanName和一个对应的ObjectFactory对象增加到singletonFactories缓存中,分析getEarlyBeanReference可以知道,它会调用SmartInstantiationAwareBeanPostProcessor这个后置处理器的getEarlyBeanReference()方法,大多数情况下,实际上相当于直接返回已经实例化的bean的引用。
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory singletonFactory = (ObjectFactory) 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);
这里就会去检查singletonFactories中是否已经有与beanName对应的ObjectFactory,有的话,直接返回由ObjectFactory创建的对象,这里也就是正在创建过程中的bean的引用。
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
代码逻辑很清楚包括以下几步