Spring源码分析 Bean创建和获取
Spring获取Bean源码
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected Object doGetBean(String name, Class requiredType, final Object args[], boolean typeCheckOnly)
throws BeansException
{
final String beanName;
Object bean;
final RootBeanDefinition mbd;
Object prototypeInstance;
beanName = transformedBeanName(name);
// 先尝试从缓存中获取bean,对于那些单例模式的Bean,缓存获取
Object sharedInstance = getSingleton(beanName);
if(sharedInstance != null && args == null)
{
if(logger.isDebugEnabled())
if(isSingletonCurrentlyInCreation(beanName))
logger.debug((new StringBuilder()).append("Returning eagerly cached instance of singleton bean '").append(beanName).append("' that is not fully initialized yet - a consequence of a circular reference").toString());
else
logger.debug((new StringBuilder()).append("Returning cached instance of singleton bean '").append(beanName).append("'").toString());
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
break MISSING_BLOCK_LABEL_544;
}
if(isPrototypeCurrentlyInCreation(beanName))
throw new BeanCurrentlyInCreationException(beanName);
BeanFactory parentBeanFactory = getParentBeanFactory();
if(parentBeanFactory != null && !containsBeanDefinition(beanName))
{
String nameToLookup = originalBeanName(name);
if(args != null)
return parentBeanFactory.getBean(nameToLookup, args);
else
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
if(!typeCheckOnly)
markBeanAsCreated(beanName);
mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
String dependsOn[] = mbd.getDependsOn();
if(dependsOn != null)
{
String arr$[] = dependsOn;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
String dependsOnBean = arr$[i$];
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
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;
}
}
final String val$beanName;
final RootBeanDefinition val$mbd;
final Object val$args[];
final AbstractBeanFactory this$0;
{
this$0 = AbstractBeanFactory.this;
beanName = s;
mbd = rootbeandefinition;
args = aobj;
super();
}
}
);
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
break MISSING_BLOCK_LABEL_544;
}
if(!mbd.isPrototype())
break MISSING_BLOCK_LABEL_399;
prototypeInstance = null;
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
afterPrototypeCreation(beanName);
break MISSING_BLOCK_LABEL_383;
Exception exception;
exception;
afterPrototypeCreation(beanName);
throw exception;
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
break MISSING_BLOCK_LABEL_544;
String scopeName = mbd.getScope();
Scope scope = (Scope)scopes.get(scopeName);
if(scope == null)
throw new IllegalStateException((new StringBuilder()).append("No Scope registered for scope '").append(scopeName).append("'").toString());
try
{
Object scopedInstance = scope.get(beanName, new ObjectFactory() {
public Object getObject()
throws BeansException
{
beforePrototypeCreation(beanName);
Object obj = createBean(beanName, mbd, args);
afterPrototypeCreation(beanName);
return obj;
Exception exception1;
exception1;
afterPrototypeCreation(beanName);
throw exception1;
}
final String val$beanName;
final RootBeanDefinition val$mbd;
final Object val$args[];
final AbstractBeanFactory this$0;
{
this$0 = AbstractBeanFactory.this;
beanName = s;
mbd = rootbeandefinition;
args = aobj;
super();
}
}
);
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch(IllegalStateException ex)
{
throw new BeanCreationException(beanName, (new StringBuilder()).append("Scope '").append(scopeName).append("' is not active for the current thread; ").append("consider defining a scoped proxy for this bean if you intend to refer to it from a singleton").toString(), ex);
}
if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass()))
{
try
{
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch(TypeMismatchException ex)
{
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Failed to convert bean '").append(name).append("' to required type [").append(ClassUtils.getQualifiedName(requiredType)).append("]").toString(), ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else
{
return bean;
}
}
如图所示,源码分析
首先获取bean的名称 beanName = transformedBeanName(name);
然后查看缓存中bean是否存在,如下图
Object sharedInstance = getSingleton(beanName);
private final Map singletonObjects = new ConcurrentHashMap(64);
private final Map alreadyCreated;
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
/*1*/
Object singletonObject = singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName))
synchronized (singletonObjects) {
singletonObject = earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory singletonFactory = (ObjectFactory) singletonFactories
.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
earlySingletonObjects.put(beanName, singletonObject);
singletonFactories.remove(beanName);
}
}
}
return singletonObject == NULL_OBJECT ? null : singletonObject;
}
/*2*/
protected void markBeanAsCreated(String beanName) {
alreadyCreated.put(beanName, Boolean.TRUE);
}
/*3*/
String dependsOn[] = mbd.getDependsOn();
if(dependsOn != null)
{
String arr$[] = dependsOn;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
String dependsOnBean = arr$[i$];
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
紧接着,如图1 通过singletonObjects缓存对象去获取对象,由于可见,Spring底层用的缓存大多数是缓存在Map结构中,缓存对象首次初始化的时候为空,构建之前会先调用 如图2-markBeanAsCreated()标明此处bean状态为构建中, 继续分析如下
如图3 后续会查看当前bean是否有依赖引用,如A依赖B,首先会把B创建成功后,然后注入到A中
下叙真实获取bean对象源码
public static transient Object instantiateClass(Constructor ctor,
Object args[]) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return ctor.newInstance(args);
} catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(),
"Is it an abstract class?", ex);
} catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(),
"Is the constructor accessible?", ex);
} catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(),
"Illegal arguments for constructor", ex);
} catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor.getDeclaringClass(),
"Constructor threw exception", ex.getTargetException());
}
}
public static void makeAccessible(Constructor ctor) {
if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor
.getDeclaringClass().getModifiers())) && !ctor.isAccessible())
ctor.setAccessible(true);
}
由此得出结论,bean创建实例是通过java反射来实现,创建之前会检查访问修饰类型,如果不是public可见的,调用setAccessible(true);得到私有构造方法来构建对象实例,接下来要把bean中默认设置的属性值注入,创建出来的单例bean对象添加到缓存中,供下次直接使用,到此bean创建和获取流程结束
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (singletonObjects) {
//Map缓存单例bean对象
singletonObjects.put(beanName,
singletonObject == null ? NULL_OBJECT : singletonObject);
singletonFactories.remove(beanName);
earlySingletonObjects.remove(beanName);
registeredSingletons.add(beanName);
}
}
总结:
SpringBean创建和获取
- Spring的bean实际上是缓存在CurrentHashMap对象中
- 创建bean之前,首先要将该bean的创建标识设定好,表示该bean已经即将被创建,其目的增强缓存效率
- 根据bean的Scope属性来确定是singleton还是prototype等范围,然后创建相应bean对象
- 通过java反射创建bean的实例
- 接下来,寻找bean的属性值,完成属性注入
- 将所创建出来的singleton对象添加到缓存中,供下次调用使用
作者简介:张程 技术研究
更多文章请关注微信公众号:zachary分解狮 (frankly0423)