spring源码---DI:实例化单例bean

★  

 接着上一节,如果在缓冲中找不到bean,那么要不就是循环依赖出问题了,要不就需要找到beanDefinitioin 进行实例化,我们这里来介绍后者。

   1.获取beanDefinitioin。

    2.创建bean(单例,原型,自定义)

    3.对创建的bean实例对象进行类型检查

 正文:

一,bean准备工作

     第一个:找到beanDefinition

//对IOC容器中 是否存在指定名称的beanDefinition 进行检测,如果当前容器不存在, 就去父容器中查找。
BeanFactory parentBeanFactory = getParentBeanFactory();  //dubug显示,为null
//父类存在,子类中第六层(最底层实现的该方法),找不到beanDefinition,则需要去父类中查找,
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
   String nameToLookup = originalBeanName(name);                  //获得原名字
   if (parentBeanFactory instanceof AbstractBeanFactory) {  //这个应该是子类
      return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);  //使用父类直接doGet创建。
   }
   else if (args != null) {        //父类只有getBean方法。
      return (T) parentBeanFactory.getBean(nameToLookup, args);
   }
   else {
      return parentBeanFactory.getBean(nameToLookup, requiredType);
   }
}

   如果本类容器没有,就去父类的容器中找,而且直接是return 所以不会走if下面的代码代码了,我们的测试demo,dubug到这里显示parentBeanFactory为null,所以并没有进入该代码块。

   第二个:获取BeanDefinition并且依赖准备 

//根据指定Bean名称 获取其父级bean的定义。  主要解决bean继承时 子类和父类 公共属性问题。
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

//获取当前bean所有依赖 bean的名称。
String[] dependsOn = mbd.getDependsOn();
//【说明】如果要创建的bean有需要依赖的(比如controller依赖service)那么这里要先创建service所有这里是递归,递归完, 还要继续执行的(而上面的递归是直接返回结果了)
if (dependsOn != null) {
  for (String dep : dependsOn) {
     registerDependentBean(dep, beanName);//把被依赖的bean注册给当前依赖的bean.
     getBean(dep);//递归调用获取当前bean的依赖。
  }
}

   第一步:获得RootBeanDefinition  这个以前没有见过,这里查了一下:https://blog.csdn.net/andy_zhang2007/article/details/86514320

       内容:基础接口是:beanDefinition,它的变种有:RootBeanDefinitionChildBeanDefinition,还有GenericBeanDefinitionAnnotatedGenericBeanDefinition,ScannedGenericBeanDefinition等等,这些概念抽象了不同的关注点。此处的getMerged...它是一个map,k-v=name-RootBean...   

       简单点,这个RootBean...就是封装了BeanDefinition,反正我们就是拿到了beanDefinition了,可以开始实例化了。!

   第二步:获取bean的所以依赖,放在一个字符串组中,应该返回的是依赖bean的name。通过它的父类AbstractBeanDefinition  的属性dependsOn直接获取。

    第三步:将依赖注册到第二层类:DefaultSingletonBeanRegistry类中,所以我们得到结论:自动注入(@Autowired)产生的bean都是单例的!

存放容器:
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
注册代码:	
public void registerDependentBean(String beanName, String dependentBeanName) {
   String canonicalName = canonicalName(beanName); //获得原名
   //将依赖的beanName 添加到两个容器中
   synchronized (this.dependentBeanMap) {
      Set<String> dependentBeans =
            this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); //获得value
      if (!dependentBeans.add(dependentBeanName)) { //添加失败,直接返回
         return;
      }
   }

   synchronized (this.dependenciesForBeanMap) {
      Set<String> dependenciesForBean =
            this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
      dependenciesForBean.add(canonicalName);
   }
}

   第四步:获取依赖的bean (这里就相当于递归了)  来到了核心的地方,doGetBean(也就是我们的第一次使用getBean ,从缓冲判断,然后自己创建bean 的那个函数)

    递归,将自动注入的bean,缓存到单例的容器中。!

二,实例化Bean

    2.1 单例bean

if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> {
      try { 
         return createBean(beanName, mbd, args); //【入】具体方法
      }...
   });
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

  内容重点是:createBean(),跳转到:AbstractAutowireCapableBeanFactory类。它是AbstractBeanFactory的直接子类。也就是第五层类,createbean() 传入的参数,第一个是beanName 第二个是beanDefinition的封装,第三个是构造参数。

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   RootBeanDefinition mbdToUse = mbd;
   //判断该bean,是否可以被当前加载器修改。
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName); //【1】
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd); //复制一份
      mbdToUse.setBeanClass(resolvedClass);
   } 
      mbdToUse.prepareMethodOverrides();    //【2】
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //【3】
      if (bean != null) {
         return bean;
      }
      Object beanInstance = doCreateBean(beanName, mbdToUse, args); //【4】
      return beanInstance;
}

     第一个方法,返回bean的class对象(调用的是AbstractBeanFactory实现的方法)

     第二个方法,效验mbdTOUse,(这里是把传入的容器中的beanDefinition复制了一份起来作为mdbToUse)

     第三个方法,如果bean配置了初始化前后处理器,则返回一个代理对象。(这里涉及到了处理器,之后再讨论重点看下一个方法)

     第四个方法,根据name和beanDefintion创建bean。(重点)

  【重点】 doCreateBean()  很长 ,位于第五层类:AbstractAutowireCapableBeanFactory类中:

   那么长的方法,大致分为五个流程

 第一流程创建bean对象

把bean封装到BeanWrapper类中。【注意】第一个流程很长,注意什么时候回来!

// Instantiate the bean. 创建bean实例对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {   //单例,用过已经存在与缓存中,获取
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) { //临时创建
   instanceWrapper = createBeanInstance(beanName, mbd, args); //【重点】
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
   mbd.resolvedTargetType = beanType;
}

     详细学习BeanWrapper参考链接:https://my.oschina.net/thinwonton/blog/1492224   

    概述:它的作用:bean的包裹类,提供了访问bean的属性值,属性编辑注册,类型转换等功能。(这里重点:属性赋值)

   重点是createBeanInstance()方法,直接创建,(本类中,又是一个很长的方法)返回类型就是一个BeanWrapper.

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // Make sure bean class is actually resolved at this point. 确认bean可解析
   Class<?> beanClass = resolveBeanClass(mbd, beanName);

   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) { //demo显示为Null
      return obtainFromSupplier(instanceSupplier, beanName);
   }
   if (mbd.getFactoryMethodName() != null) {//demo显示为Null  工厂方法进行实例化
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }

   // Shortcut when re-creating the same bean...
   boolean resolved = false;
   boolean autowireNecessary = false;
   if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
         if (mbd.resolvedConstructorOrFactoryMethod != null) {
            resolved = true;
            autowireNecessary = mbd.constructorArgumentsResolved;
         }
      }
   }
   if (resolved) { //false
      if (autowireNecessary) {//配置了自动装配属性,使用容器的自动装配进行实例化
         return autowireConstructor(beanName, mbd, null, null);
      }
      else { 
         return instantiateBean(beanName, mbd);
      }
   }

   // Candidate constructors for autowiring?  使用构造方法进行实例化
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
   }

   //默认的 无参构造方法实例化bean对象
   return instantiateBean(beanName, mbd);// 走这里
}

     这里直接进行了bean的实例化 ,整个方法分为三个块,注意观察return的位置。

      第一个 使用工厂方法对bean 实例化:Supplier接口,只有一个方法T get()。每次调用get() 都会调用构造方法创建一个新对象。

protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
   String outerBean = this.currentlyCreatedBean.get();
   this.currentlyCreatedBean.set(beanName);
   Object instance;
   try {
      instance = instanceSupplier.get(); //重点
   }
   finally {...   }
   BeanWrapper bw = new BeanWrapperImpl(instance);
   initBeanWrapper(bw);
   return bw;
}

 第二个 使用容器的自动装配方法 进行实例化

           这里的关键是resolved 标识符,args要确保是null,才能进行自动装配。这里也是一个入口而已,

	protected BeanWrapper autowireConstructor(
			String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

		return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
	}

   注意,又是ConstructorResolver  的方法。 

 第三个:使用默认的无参构造方法进行实例化。也是demo测试例子 所走的路线

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
   try {
      Object beanInstance;
      final BeanFactory parent = this;
      if (System.getSecurityManager() != null) {
         beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
               getInstantiationStrategy().instantiate(mbd, beanName, parent),
               getAccessControlContext());
      }
      else { //demo 走这里
         beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
      }
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      initBeanWrapper(bw);
      return bw;
   }
}

 重点是getInstantiationStrategy().instantiate(mbd, beanName, parent) 实现初始化。instantiate()方法位于SimpleInstantiationStratey类

protected InstantiationStrategy getInstantiationStrategy() {
   return this.instantiationStrategy;
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
   // Don't override the class with CGLIB if no overrides.
   if (!bd.hasMethodOverrides()) {
      Constructor<?> constructorToUse;
      synchronized (bd.constructorArgumentLock) {
         //获取对象的构造方法or 工厂方法
         constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
         if (constructorToUse == null) {
            final Class<?> clazz = bd.getBeanClass();
            try {
               if (System.getSecurityManager() != null) {
                  constructorToUse = AccessController.doPrivileged(
                        (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
               }
               else { //获取构造方法 
                  constructorToUse = clazz.getDeclaredConstructor();
               }
               bd.resolvedConstructorOrFactoryMethod = constructorToUse;
            }
         }
      }  //调用工具类,传入构造方法,继续实例化 【入】
      return BeanUtils.instantiateClass(constructorToUse);
   }
   else {
      // Must generate CGLIB subclass.
      return instantiateWithMethodInjection(bd, beanName, owner);
   }
}

  如果bean的方法被覆盖了,则使用cglib进行实例化,我们先看简单的jdk反射机制实例化: 

    第一个return 直接使用BeanUtils 得到了bean的实例化对象了。使用的是jdk 的反射,

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
   Assert.notNull(ctor, "Constructor must not be null");
   try {
      ReflectionUtils.makeAccessible(ctor);
      return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
            KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
   }
  ....
}

      第二个return  使用的是cglib代理模式,方法跟踪:来到CglibSubcalssInstantiationStrategy类中:

protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
   return instantiateWithMethodInjection(bd, beanName, owner, null);
}

protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
      @Nullable Constructor<?> ctor, @Nullable Object... args) {
   return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}

创建了一个CglibSubclassCreator类,它是一个内部类 ,重点是instantiate()方法,不同于第一个return 代码的地方就是,class对象的获取,第一个方法是直接获取,第二个是通过cglib代理创建Class对象,最后同样通过BeanUtils进行实例化。

public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {
   //创建代理子类  【入】
   Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
   Object instance;
   if (ctor == null) {
      instance = BeanUtils.instantiateClass(subclass);
   }
   else {
      try {
         Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
         instance = enhancedSubclassConstructor.newInstance(args);
      }
   }
   Factory factory = (Factory) instance;
...
   return instance;
}
//------------------------------
private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
	//cglib中的类
	Enhancer enhancer = new Enhancer();
	//将bean本身作为基类
	enhancer.setSuperclass(beanDefinition.getBeanClass());
	enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
	if (this.owner instanceof ConfigurableBeanFactory) {
		ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
		enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
	}
	enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
	enhancer.setCallbackTypes(CALLBACK_TYPES);
	//使用cglib的..方法生成实例对象。
	return enhancer.createClass();
}

分析:我们先从最下面的方法开始分析,Enhancer这是cglib的标准类,把beanDefinition的class对象传给他,作为父类,然后它创建一个新的字节码,返回一个新的class对象了。然后使用BeanUtils返回实例化对象。

  在这里就成功实例化了bean。现在回到AbstractAutowireCapableBeanFactory类的doCreateBean()方法:

第二流程:调用后置处理器:

synchronized (mbd.postProcessingLock) {
   if (!mbd.postProcessed) {
      applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      mbd.postProcessed = true;
   }
}
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof MergedBeanDefinitionPostProcessor) {
         MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
         bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
      }
   }
}

第三流程:缓存到第二层:DefaultSingletonBeanRegistry类中

//向容器中缓存单例模式的 bean ,防止死循环
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
      isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //【入】
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
   synchronized (this.singletonObjects) {
      if (!this.singletonObjects.containsKey(beanName)) {
         this.singletonFactories.put(beanName, singletonFactory); //【放入】
         this.earlySingletonObjects.remove(beanName);
         this.registeredSingletons.add(beanName);
      }
   }
}

第四流程bean对象的初始化,依赖注入。

Object exposedObject = bean;
try {  //对Bean属性进行依赖注入 【入】
   populateBean(beanName, mbd, instanceWrapper);
   //对Bean实例对象进行初始化,使用后置处理器
   exposedObject = initializeBean(beanName, exposedObject, mbd);
}

  第一个方法,populateBean() 这个方法也是比较长。位于第五层:AbstractAutowireCapableBeanFactory类

可以参考:https://blog.csdn.net/qwe6112071/article/details/85225507  同时也可以看我下一篇博文,这里就不叙述了!

然后进行bean实例的 初始化,initializeBean()方法,这个方法里面调用后置处理器,和AOP有关,所以我们在AOP章节再分析。

第五流程:获取bean对象

if (earlySingletonExposure) {
   //获取指定名称的 已注册的 单列模式的 bean对象
   Object earlySingletonReference = getSingleton(beanName, false);
   if (earlySingletonReference != null) {
      if (exposedObject == bean) { //demo走这里
         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);
            }
         }
        ....
}

到这里,我们就成功的通过单例模式,创建获得了bean实例对象,并且完成了依赖注入,下一节,我们将继续分析原型模式的bean对象如何实例化!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值