getBean方法(二)

这次这要分析的是 createBean () 方法中的核心方法do createBean()方法
 
resolveBeforeInstantiation()这个方法中没有返回bean的实例的话,就走下面的核心方法doCreateBean创建bean,
 
protected Object doCreateBean (String beanName , RootBeanDefinition mbd , @Nullable Object[] args)
throws BeanCreationException {
 
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this . factoryBeanInstanceCache .remove(beanName) ;
}
if (instanceWrapper == null ) {
// 创建实例 ,
instanceWrapper = createBeanInstance(beanName , mbd , args) ;
}
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 {
//CommonAnnotationBeanPostProcessor 支持了 @PostConstruct @PreDestroy,@Resource 注解
//AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value 注解
//BeanPostProcessor 接口的典型运用,这里要理解这个接口
// 对类中注解的装配过程
/**
* 实例化完成后接下来就需要对类中的属性进行依赖注入操作,
* 但是类里面属性和方法的依赖注入往往用 @Autowired 或者 @Resource 注解,
* 那么这些注解的依赖注入是如何完成的呢?
* 核心方法为 applyMergedBeanDefinitionPostProcessors 也是通过 BeanPostProcessor 接口类型实例来挨个处理的。
*
* BeanPostProcessor 接口
* (2) 收集 @Resource @Autowired @Value @PostConstruct @PreDestroy 注解的方法和属性埋点
* 过滤的接口类型是: MergedBeanDefinitionPostProcessor
* 调用的方法是: postProcessMergedBeanDefinition
*/
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.
// 是否 单例 bean 提前暴露
boolean earlySingletonExposure = (mbd.isSingleton() && this . allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName)) ;
if (earlySingletonExposure) {
if ( logger .isTraceEnabled()) {
logger .trace( "Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references" ) ;
}
/**
* BeanPostProcessor 接口
* (3). 循环依赖解决中 bean 的提前暴露埋点
* 过滤的接口类型是: SmartInstantiationAwareBeanPostProcessor
* 调用的方法是: getEarlyBeanReference
*/
addSingletonFactory(beanName , () -> getEarlyBeanReference( beanName , mbd , bean )) ;
}
 
// Initialize the bean instance.
Object exposedObject = bean ;
try {
//Bean 实例化完成、并且收集完 @Resource @Autowired 注解以后就开始依赖注入:
//ioc di ,依赖注入的核心方法,
populateBean(beanName , mbd , instanceWrapper) ;
//bean 实例化 +ioc 依赖注入完以后的调用,
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<>(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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example." ) ;
}
}
}
}
 
// Register bean as disposable.
try {
// 注册 bean 销毁时的类 DisposableBeanAdapter
registerDisposableBeanIfNecessary(beanName , bean , mbd) ;
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription() , beanName , "Invalid destruction signature" , ex) ;
}
 
return exposedObject ;
}
 
先看第一个核心方法createBeanInstance()方法: 根据beanName,mbd,args 创建  BeanWrapper
 
 
   先是拿到class的类信息  ( 工厂方法、构造函数自动装配、简单实例化 )
        如果有工厂方法(类中有方法上有@Bean,xml中有 factory-method )就使用工厂方法实例化bean对象.
        我们先看下 构造函数自动注入   determineConstructorsFromBeanPostProcessors()方法
调用 SmartInstantiationAwareBeanPostProcessor  的 determineCandidateConstructors  方法,该方法可以返回用于beanClass的候选构造函数,使用 @Autowire注解修饰的
构造函数,则该构造函数在这边会被 AutowiredAnnotationBeanPostProcessor  找到.
 
 
 
 
resolveConstructorArguments() 方法通过解析mbd中构造器的参数,返回参数个数.
createArgumentArray()方法 会触发构造函数中参数的getBean操作,会实例化参数的值,我们深入看看
 
 
进入到resolveAutowiredArgument()方法
 
 
  进入到resolveDependency()中
 
解析依赖关系,返回的 result 为创建好的依赖对象的 bean 实例 ,  进入到doResolveDependency()方法
 
 
descriptor.resolveCandidate(autowiredBeanName, type, this);
最后在这个方法中触发了beanFactory.getBean(beanName);方法走向了构造器参数的实例化道路.
 
总结:主要是分析了有参构造器的实例化
    
    从  createBeanInstance 开始 
      1.判断 mbd.getFactoryMethodName() != null  (如果有FactoryMethodName属性 方法上面@Bean 或者 xml里面有factory-method 标签  没有class属性  )     判断不成立       
      2. determineConstructorsFromBeanPostProcessors()    
                            获取所有的  BeanPostProcessor 接口类型的对象.然后判断是否是  SmartInstantiationAwareBeanPostProcessor   类型的 ,然后在循环调用  determineCandidateConstructors   方法,
                           该方法是 获取有 @Autowired 注解的构造函数埋点.
     3.如果构造参数不为空 autowireConstructor()方法
                       优先实例化 实例化构造器中的对象   
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值