• spring-beanFactory二


    上一篇只是将xml解析为bean definitions,这一篇来看getBean通过bean definition得到实例。

    1 //以XmlBeanFactory为例
    2 BeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring/spring-test.xml"));
    3 MyBean bean = (MyBean) factory.getBean("myBean");
    4 System.out.println(bean.getBeanName());//myBean
    1 public class MyBean {
    2     private String beanName = "myBean";
    3     public String getBeanName() {
    4         return beanName;
    5     }
    6     public void setBeanName(String beanName) {
    7         this.beanName = beanName;
    8     }
    9 }
    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <beans xmlns="http://www.springframework.org/schema/beans"
    3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5     <bean id="myBean" class="com.zyong.spring.beanfactory.MyBean"/>
    6 </beans>
    1 public Object getBean(String name) throws BeansException {
    2     //name, requiredType, args, typeCheckOnly
    3     return doGetBean(name, null, null, false);
    4 }
     1 //doGetBean会真正的实例化对象,并回调beanFactory(BeanPostProcessor)、
     2 //bean(init,@PostConstruct和@PreDestroy通过CommonAnnotationBeanPostProcessor或开启<context:annotation-config />来支持)的相关方法
     3 protected <T> T doGetBean(
     4         final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
     5         throws BeansException {
     6         
     7     // Eagerly check singleton cache for manually registered singletons.
     8     //尝试从缓存中获取,首先会尝试从singletonObjects获取,再尝试从singletonFactories中获取获取beanFactory(beanName是beanFactory的名字),如果获取到则调用getObject获得bean
     9     Object sharedInstance = getSingleton(beanName);
    10     if (sharedInstance != null && args == null) {
    11         if (logger.isDebugEnabled()) {
    12             if (isSingletonCurrentlyInCreation(beanName)) {
    13                 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
    14                         "' that is not fully initialized yet - a consequence of a circular reference");
    15             }
    16             else {
    17                 logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
    18             }
    19         }
    20         //从bean实例中获取对象,可能是bean实例自身,如果bean实例是一个beanFactory,则返回beanFactroy创建的对象
    21         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    22     }else{
    23         // Check if bean definition exists in this factory.
    24         BeanFactory parentBeanFactory = getParentBeanFactory();
    25         //如果本beanFactory不包含该beanName的bean definition,则从父级beanFactory获取bean
    26         if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    27             // Not found -> check parent.
    28             String nameToLookup = originalBeanName(name);
    29             return (T) parentBeanFactory.getBean(nameToLookup, args);
    30         }
    31         
    32         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    33         checkMergedBeanDefinition(mbd, beanName, args);
    34 
    35         // Guarantee initialization of beans that the current bean depends on.
    36         //这里只是为当前bean注册依赖,并没有注入,注册依赖是为了在销毁当前bean之前,先销毁依赖(为了实现该功能,需要2个注册表,一个是bean->dependences,另一个是dependence->beans)
    37         String[] dependsOn = mbd.getDependsOn();
    38         if (dependsOn != null) {
    39             for (String dep : dependsOn) {
    40                 if (isDependent(beanName, dep)) {
    41                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    42                             "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
    43                 }
    44                 registerDependentBean(dep, beanName);
    45                 //递归创建依赖bean
    46                 getBean(dep);
    47             }
    48         }
    49         
    50         //从这里开始真正创建bean
    51         // Create bean instance.
    52         if (mbd.isSingleton()) {
    53             sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {//策略模式,ObjectFactory不同,创建bean的策略也会有差异
    54                 @Override
    55                 public Object getObject() throws BeansException {
    56                     try {
    57                         //重要方法
    58                         return createBean(beanName, mbd, args);
    59                     }
    60                     catch (BeansException ex) {
    61                         // Explicitly remove instance from singleton cache: It might have been put there
    62                         // eagerly by the creation process, to allow for circular reference resolution.
    63                         // Also remove any beans that received a temporary reference to the bean.
    64                         destroySingleton(beanName);
    65                         throw ex;
    66                     }
    67                 }
    68             });
    69             //与之前从缓存获取bean实例类似
    70             bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    71         }else if(mbd.isPrototype()){
    72             ......
    73         }else{
    74             ......
    75         }
    76         
    77     }//else
    78 
    79 }
    1 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    2     Object singletonObject = this.singletonObjects.get(beanName);
    3     if (singletonObject == null) {
    4         singletonObject = singletonFactory.getObject();//getObject会回调createBean
    5         //注册bean实例,即放入map中
    6         addSingleton(beanName, singletonObject);
    7     }
    8     return (singletonObject != NULL_OBJECT ? singletonObject : null);
    9 }
     1 //createBean的主要逻辑,这里就真正开始创建bean的各种“花招”了
     2 protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
     3     // Make sure bean class is actually resolved at this point, and
     4     // clone the bean definition in case of a dynamically resolved Class
     5     // which cannot be stored in the shared merged bean definition.
     6     //加载bean的class,并存入bean definition
     7     Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
     8     if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
     9         mbdToUse = new RootBeanDefinition(mbd);
    10         mbdToUse.setBeanClass(resolvedClass);
    11     }
    12     // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    13     //如果bean实现了InstantiationAwareBeanPostProcessor,
    14     //这里就会调用InstantiationAwareBeanPostProcessor的Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)接口来创建bean,
    15     //如果返回非null,则继续调用boolean postProcessAfterInstantiation(Object bean, String beanName)接口
    16     //PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)有机会在注入前执行
    17     Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    18     //如果通过InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法得到一个实例,直接返回
    19     if (bean != null) {
    20         return bean;
    21     }
    22     //如果通过InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法无法得到一个实例,则进行常规实例化工作(实例化、注入、BeanPostProcessor等)
    23     //重要方法
    24     Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    25     return beanInstance;
    26 }
     1 //doCreateBean的主要逻辑
     2 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
     3     throws BeanCreationException {
     4     //使用工厂方法、构造器注入、简单实例化等策略实例化bean(不是策略模式,只是通过bean definition来决定使用哪种策略,类似switch)
     5     //BeanWrapper是bean的包装类,beanWrapper提供了便捷的方法去更新bean的字段、访问bean的方法,用于注入
     6     BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);//离我们很近
     7     final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
     8     //MergedBeanDefinitionPostProcessor的void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)
     9     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    10     // Initialize the bean instance.
    11     //exposedObject即暴露的bean、原生的bean
    12     Object exposedObject = bean;
    13     //先执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation,
    14     //再执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues,最后再进行xml注入。
    15     //所谓populateBean就是根据该bean在xml的配置信息来填充bean,这些信息已经被解析为BeanDefinition。
    16     populateBean(beanName, mbd, instanceWrapper);
    17     //什么情况下bean==null?
    18     if (exposedObject != null) {
    19         //初始化bean
    20         //invokeAwareMethods(回调BeanNameAware、BeanClassLoaderAware、BeanFactoryAware的相关方法)、
    21         //applyBeanPostProcessorsBeforeInitialization(回调BeanPostProcessor的postProcessBeforeInitialization方法)、
    22         //invokeInitMethods(回调InitializingBean的afterPropertiesSet,以及init-method)、
    23         //applyBeanPostProcessorsAfterInitialization(回调BeanPostProcessor的postProcessAfterInitialization方法)
    24         exposedObject = initializeBean(beanName, exposedObject, mbd);//离我们很近
    25     }
    26     // Register bean as disposable.
    27     registerDisposableBeanIfNecessary(beanName, bean, mbd);
    28 }
  • 相关阅读:
    多状态场景:后端只记录行为,不记录行为的含义,比如产品定义的状态值含义;行为是客观的,不变的。
    Golang协程池的使用 原创 360质量效能 360质量效能 2021-05-28
    &strct new
    【Golang】图解函数调用栈
    Mybatis-Plus的应用场景及注入SQL原理分析
    倒计时时间到触发事件
    浅析软件供应链攻击之包抢注低成本钓鱼
    腾讯代码安全指南开源,涉及C/C++、Go等六门编程语言 https://mp.weixin.qq.com/s/yzg5uVnoJDTyaH2Wn8Vo7w
    58黄页标签提取及海量多分类优化
    引用站点策略: strict-origin-when-cross-origin 引用站点策略: no-referrer-when-downgrade
  • 原文地址:https://www.cnblogs.com/holoyong/p/7364135.html
Copyright © 2020-2023  润新知