Spring源码解析 -- 读取bean元数据
spring源码解析 -- 构造bean
spring源码解析 -- 注入属性
spring源码解析 -- Spring Context
Spring源码解析 -- AOP原理(1)
Spring源码解析 -- AOP原理(2)
Spring源码解析 -- SpringMvc原理
源码分析基于spring 4.3.x
前面文章已经分析了spring如何加载xml配置中的bean元数据,现在来分析一下spring构造bean的过程。
关于阅读源码的思路,可参考 -- 如何阅读java源码
BeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("application.xml"));
Blog bean = (Blog)xmlBeanFactory.getBean("blog");
XmlBeanFactory的父类AbstractBeanFactory是spring中一个很重要的类,他为BeanFactory提供基础服务。构造bean就是由该类实现的。
AbstractBeanFactory#doGetBean
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
Object sharedInstance = getSingleton(beanName); // #1
if (sharedInstance != null && args == null) {
...
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); // #2
}
else {
if (isPrototypeCurrentlyInCreation(beanName)) { // #3
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // #4
...
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName); // #5
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // #6
checkMergedBeanDefinition(mbd, beanName, args);
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);
try {
getBean(dep); // #7
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> { // #8
try {
return createBean(beanName, mbd, args); // #9
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
...
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) { // #10
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
#1
单例的bean,先从缓冲中查询
getSingleton方法会查询
singletonObject,earlySingletonObjects,singletonFactories等缓存,它们都是简单的map,缓存了单例的bean,正在创建的bean和ObjectFactory对象。
#2
如果构造的bean是FactoryBean,进行对应的处理
getObjectForBeanInstance方法会根据参数beanInstance进行处理,如果beanInstance是FactoryBean,会调用其getObject()
方法创建bean,如果不是,返回直接返回该beanInstance参数。
FactoryBean是spring提供的一个扩展接口,用户实现该接口可以自定义bean的创建。
#3
如果现在正在创建这个bean,则直接报错,这时很可能陷入循环引用了
#4
当前BeanFactory不存在对应的BeanDefinition,尝试通过父BeanFactory构造bean
#5
标记这个bean正在构造中
#6
获取BeanDefinition
前面解析spring加载bean数据的文章中说过,spring会将bean元数据转化为BeanDefinition,存入DefaultListableBeanFactory#beanDefinitionMap属性中。
getMergedLocalBeanDefinition方法会获取对应BeanDefinition,如果BeanDefinition存在ParentName,会获取父BeanDefinition,再合并元数据。
#7
先构造依赖的bean
#8
使用ObjectFactory构造并注册一个bean,getSingleton方法也要完成构造bean的准备和善后工作。
#9
匿名的ObjectFactory,调用AbstractAutowireCapableBeanFactory#createBean进行实际的构造bean工作
#10
bean类型转换
spring中bean有singleton,prototype等范围,这里只关注singleton类型的bean的构造过程。
#8
步骤,DefaultSingletonBeanRegistry#getSingleton(注意getSingleton有重载方法)
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
...
beforeSingletonCreation(beanName); // #1
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject(); // #2
newSingleton = true;
}
...
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject); // #3
}
}
return singletonObject;
}
}
#1
仅做错误检查,也是提供给子类的扩展方法
#2
真正构造bean的方法,调用AbstractBeanFactory#doGetBean方法#9
步骤的匿名类处理,实际调用AbstractAutowireCapableBeanFactory#createBean
#3
单例的bean,加入缓冲中
真正的构造bean方法
AbstractAutowireCapableBeanFactory#createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
Class> resolvedClass = resolveBeanClass(mbd, beanName); // #1
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides(); // #2
}
...
try {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // #3
if (bean != null) {
return bean;
}
}
...
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args); // #4
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
...
}
#1
确保jdk已加载bean的class
#2
对bean的lookup-method和replace-method做检查工作
#3
spring的扩展机制,调用BeanPostProcessor#postProcessBeforeInstantiation方法,
注意,如果resolveBeforeInstantiation返回非null对象,这里将直接返回该对象作为bean,spring不再构造该bean。
#4
继续构造bean
AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); // #1
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args); // #2
}
final Object bean = instanceWrapper.getWrappedInstance();
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); // #3
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
...
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); // #4
exposedObject = initializeBean(beanName, exposedObject, mbd); // #5
}
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);
}
}
...
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd); // #6
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
#1
查询BeanWrapper缓冲
#2
构造一个空的(属性未注入)bean,生成BeanWrapper
#3
spring扩展机制,调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
#4
populateBean负责注入属性到bean中,后面有对应文章解析该步骤
#5
spring扩展机制,调用Aware方法和init方法,并调用BeanPostProcessor#postProcessAfterInitialization方法。
#6
如果bean存在Destroy方法,或存在对应的DestructionAwareBeanPostProcessor,注册该bean为disposable。(该bean销毁时要调用对应的销毁机制)
这里涉及到循环引用的处理,比较繁琐,所以省略了很多代码,只保留bean创建相关的代码。
BeanWrapper是对bean的包装类,提供了对bean的class,property进行操作的方法。
#2
步骤,AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
Class> beanClass = resolveBeanClass(mbd, beanName); // #1
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) { // #2
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) { // #3
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null); // #4
}
else {
return instantiateBean(beanName, mbd); // #5
}
}
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // #6
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
#1
获取bean的class
#2
如果存在factoryMethod,通过factoryMethod构造bean
#3
判断该class已经构造过bean了
#4
使用之前选择好的构造函数构造bean
#5
使用无参构造函数构造bean
#6
spring根据构造函数的参数,自行选择构造函数,逻辑较复杂。
下面看看使用无参构造方法构造bean,AbstractAutowireCapableBeanFactory#instantiateBean -> SimpleInstantiationStrategy#instantiate
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
if (bd.getMethodOverrides().isEmpty()) {
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");
}
try {
if (System.getSecurityManager() != null) {
...
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null); // #1
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse; // #2
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse); // #3
}
else {
return instantiateWithMethodInjection(bd, beanName, owner); // #4
}
}
#1
获取无参构造函数
#2
添加无参构造函数加入到BeanDefinition缓存中
#2
BeanUtils#instantiateClass通过构造函数构造bean
#3
bean中存在lookup-method或replace-method,必须使用CGLIB构造bean
到这里,bean已经构造完成,下一步就是注入属性了。
如果您觉得本文不错,欢迎关注我的微信公众号,您的关注是我坚持的动力!