spring源码解析---spring-core(三)

getBean

  • 这里便是bean初始化的核心逻辑。源码比较复杂,分开说。以getBean(String name)为例。AbstractBeanFactory.getBean:
  • @Overridepublic Object getBean(String name) throws BeansException {
    return doGetBean(name, nullnullfalse);
    }
  • 第二个参数表示bean的Class类型,第三个表示创建bean需要的参数,最后一个表示不需要进行类型检查。
 

手动注册bean检测

  • 前面注册环境一节说过,Spring其实手动注册了一些单例bean。这一步就是检测是不是这些bean。如果是,那么再检测是不是工厂bean,如果是返回其工厂方法返回的实例,如果不是返回bean本身。

Object sharedInstance = getSingleton(beanName);

if (sharedInstance != null && args == null) {

bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

}

 

检查父容器

  • 如果父容器存在并且存在此bean定义,那么交由其父容器初始化:

BeanFactory parentBeanFactory = getParentBeanFactory();

if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {

// Not found -> check parent.

//此方法其实是做了前面beanName转化的逆操作,因为父容器同样会进行转化操作

String nameToLookup = originalBeanName(name);

if (args != null) {

// Delegation to parent with explicit args.

return (T) parentBeanFactory.getBean(nameToLookup, args);

} else {

// No args -> delegate to standard getBean method.

return parentBeanFactory.getBean(nameToLookup, requiredType);

}

}

依赖初始化

  • bean可以由depends-on属性配置依赖的bean。Spring会首先初始化依赖的bean。

String[] dependsOn = mbd.getDependsOn();

if (dependsOn != null) {

for (String dependsOnBean : dependsOn) {

//检测是否存在循环依赖

if (isDependent(beanName, dependsOnBean)) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,

"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");

}

registerDependentBean(dependsOnBean, beanName);

getBean(dependsOnBean);

}

}

  • registerDependentBean进行了依赖关系的注册,这么做的原因是Spring在即进行bean销毁的时候会首先销毁被依赖的bean。依赖关系的保存是通过一个ConcurrentHashMap<String, Set>完成的,key是bean的真实名字。

Singleton初始化

  • 虽然这里大纲是Singleton初始化,但是getBean方法本身是包括所有scope的初始化,在这里一次说明了。

if (mbd.isSingleton()) {

sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {

@Override

public Object getObject() throws BeansException {

return createBean(beanName, mbd, args);

}

});

bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

}

 

getSingleton方法

是否存在

  • 首先会检测是否已经存在,如果存在,直接返回:

synchronized (this.singletonObjects) {

Object singletonObject = this.singletonObjects.get(beanName);

}

  • 所有的单例bean都保存在这样的数据结构中: ConcurrentHashMap<String, Object>。

bean创建

  • 源码位于AbstractAutowireCapableBeanFactory.createBean,主要分为几个部分:

lookup-method检测

  • 此部分用于检测lookup-method标签配置的方法是否存在:

RootBeanDefinition mbdToUse = mbd;

mbdToUse.prepareMethodOverrides();

prepareMethodOverrides:

public void prepareMethodOverrides() throws BeanDefinitionValidationException {

// Check that lookup methods exists.

MethodOverrides methodOverrides = getMethodOverrides();

if (!methodOverrides.isEmpty()) {

Set<MethodOverride> overrides = methodOverrides.getOverrides();

synchronized (overrides) {

for (MethodOverride mo : overrides) {

prepareMethodOverride(mo);

}

}

}

}

prepareMethodOverride:

protected void prepareMethodOverride(MethodOverride mo) {

int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());

if (count == 0) {

throw new BeanDefinitionValidationException(

"Invalid method override: no method with name '" + mo.getMethodName() +

"' on class [" + getBeanClassName() + "]");

} else if (count == 1) {

// Mark override as not overloaded, to avoid the overhead of arg type checking.

mo.setOverloaded(false);

}

}

InstantiationAwareBeanPostProcessor触发

  • 在这里触发的是其postProcessBeforeInitialization和postProcessAfterInstantiation方法。

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

if (bean != null) {

return bean;

}

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

return beanInstance;

  • 继续:

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;

}

  • 从这里可以看出,如果InstantiationAwareBeanPostProcessor返回的不是空,那么将不会继续执行剩下的Spring初始化流程,此接口用于初始化自定义的bean,主要是在Spring内部使用。

  • doCreateBean

    创建(createBeanInstance)

    MergedBeanDefinitionPostProcessor

    属性解析

    属性设置

    初始化

    getObjectForBeanInstance

         位于AbstractBeanFactory,此方法的目的在于如果bean是FactoryBean,那么返回其工厂方法创建的bean,而不是自身。

  • Prototype初始化

AbstractBeanFactory.doGetBean相关源码:

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);

}

  • beforePrototypeCreation

此方法用于确保在同一时刻只能有一个此bean在初始化。

  • createBean

和单例的是一样的,不在赘述。

  • afterPrototypeCreation

和beforePrototypeCreation对应的,你懂的。

  • 总结

      可以看出,初始化其实和单例是一样的,只不过单例多了一个是否已经存在的检查。

 

其它Scope初始化

其它就指的是request、session。此部分源码:

else {

String scopeName = mbd.getScope();

final Scope scope = this.scopes.get(scopeName);

if (scope == null) {

throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");

}

Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {

@Override

public Object getObject() throws BeansException {

beforePrototypeCreation(beanName);

try {

return createBean(beanName, mbd, args);

}

finally {

afterPrototypeCreation(beanName);

}

}

});

bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);

}


 

原文: https://app.yinxiang.com/fx/65a10c5a-2ead-4507-9e44-37489f6569f2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值