分析spring源码第五(三)篇:Spring中Bean的解析、加载、创建 过程总结

一、IOC type
   1.Xml               -- 配置bean
   2.Annotation        -- @Compoment
   3.Class             -- @Configuration
   4.Properties,YML    -- @EnableConfigurationProperties(User.class)   @ConfigurationProperties("bnb.user")

  二、IOC 注入方式
   1.Setter
   2.Constructor
   3.Factory-method

  三、Why IOC
   1.模块化
   2.可重用性
   3.易于扩展
   4.可维护

   四、Spring IOC API
   1.BeanDefinition                  -- 描述bean的实例,有属性值,构造参数值
   2.Resource and ResourceLoader     -- 资源和加载资源
   3.BeanFactory                     -- spring bean容器的根接口,定义了容器最基本的功能
   4.ApplicationContext              -- 为应用程序提供配置的中心接口


   五、Spring IOC  process resource

      核心: XML -->  c  --> BeanWrapper(实现依赖注入与类型转化) -> Object (获取我们要的对象)

      1. BeanDefinition 处理过程

       xml or properties ---> ResourceLoader  --->  Resource  --> XXXReader (XmlBeanDefinitionReader/)  -->  BeanDefinition   (主要是这两种解析值的形式  ConstructorArgumentValues 和 MutablePropertyValues)

        new ClassPathXmlApplicationContext("")
            -->  org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory
            -->  org.springframework.context.support.AbstractApplicationContext.refreshBeanFactory
            -->  org.springframework.context.support.AbstractRefreshableApplicationContext.loadBeanDefinitions
            -->  org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)

         最终XML解析 是在BeanDefinitionParserDelegate类中完成的

      2. BeanWrapper  处理过程
         Spring的基础设施的中心接口,继承以下四个接口:
         ConfigurablePropertyAccessor
         PropertyAccessor
         PropertyEditorRegistry
         TypeConverter


     3. 依赖注入过程
        Java实例过程:   创建对象  -->  设置属性 --> 初始化方法
        IOC实例化过程:   CreateBeanInstance  -->  populateBean  -->  initializeBean

        CreateBeanInstance    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean

     4.spring 类型转换
      类型转换核心类 TypeConverterDelegate 方法 convertIfNecessary
        ConversionService
        PropertyEditor


     5.spring 容器扩展

     BeanPostProcessor :定制化bean逻辑,bean 后置处理器   典型应用场景:

     注解式依赖注入  @Autowired  @Value    AutowiredAnnotationBeanPostProcessor  (依赖注入的过程 其实就是根据注解获取注解bean的对象值,然后根据Java反射将bena注入进去)

     AOP的实现

     Spring容器感知


   六.
     总结 IOC 过程 BeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("beanUserTest.xml"));
     1. xml -> ResourceLoader -> Resource
     2.XmlBeanDefinitionReader.loadBeanDefinitions(resource) -> XmlBeanDefinitionReader.loadBeanDefinitions(new EncodedResource(resource))
     3.XmlBeanDefinitionReader.doLoadBeanDefinitions(InputSource inputSource, Resource resource)
     3.1. 将resource转化成document                        Document doc = XmlBeanDefinitionReader.doLoadDocument(inputSource, resource)     ->  DocumentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,getValidationModeForResource(resource), isNamespaceAware());
     3.2. reader读取document为注册beanDefinition作准备     XmlBeanDefinitionReader.registerBeanDefinitions(Document doc, Resource resource) ->  DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(Document doc, XmlReaderContext readerContext) -> DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root)
     3.3. 用自定义或默认解析器解析element                   DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root)      ->  DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) -> delegate.parseDefaultElement(ele) / delegate.parseCustomElement(root)
     3.4. 用默认解析器解析element过程     DefaultBeanDefinitionDocumentReader.parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)
     3.4.1  包含import标签的,则找出引入的resource最后在递归调用loadBeanDefinitions(resource)再次解析  DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(Element ele) -> AbstractBeanDefinitionReader.loadBeanDefinitions(Resource... resources) ->  XmlBeanDefinitionReader.loadBeanDefinitions(Resource resource)
     3.4.2  包含alias别名的,解析出bean的别名并在aliasRegistered进行注册  DefaultBeanDefinitionDocumentReader.processAliasRegistration(Element ele) ->  ReaderContext.fireAliasRegistered(name, alias, extractSource(ele)) -> EmptyReaderEventListener.aliasRegistered(AliasDefinition aliasDefinition)
     3.4.3  包含bean标签的,则解析出bean并进行bean的注册到map中   DefaultBeanDefinitionDocumentReader.processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)  ->  BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele) -> BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())
     3.4.4  包含beans标签的 又重新进入3.2步 DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root)
     4.获取bean xmlBeanFactory.getBean("test"), AbstractBeanFactory.getBean(name) -> AbstractBeanFactory.doGetBean(name,requiredType)
     4.1  转化成真正的bean名,name可能是别名或工厂名等   String beanName = transformedBeanName(name)
     4.2  从缓存中获取单利bean,获取到则返回 Object sharedInstance = getSingleton(beanName)
     4.3 如果4.2 没有获取到,则获取bean的所有依赖,并将依赖进行注册和创建  String[] dependsOn = mbd.getDependsOn() ->  DefaultSingletonBeanRegistry.registerDependentBean(dep, beanName) -> AbstractBeanFactory.getBean(dep);
     4.4 如果是单例 mbd.isSingleton(),  AbstractAutowireCapableBeanFactory.createBean(beanName, rootBeanDefinition,args)
     4.4.1 给BeanPostProcessors处理器一个返回代理而不是目标bean实例的机会。   AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)
     4.4.1.1  实例化前置处理器 applyBeanPostProcessorsBeforeInstantiation(targetType, beanName)
     4.4.1.2  实例化后置处理器 applyBeanPostProcessorsAfterInitialization(bean, beanName)
     4.4.2 创建bean,  doCreateBean(beanName, mbdToUse, args)
     4.4.2.1  创建bean实例对象   createBeanInstance(beanName, mbd, args)
     4.4.2.1.1    有指定的构造函数的创建bean对象  autowireConstructor(beanName, mbd, null, null)
     4.4.2.1.2    使用默认构造函数创建bean对象   instantiateBean(beanName, mbd)
     4.4.2.2  设置属性,填充值   populateBean(beanName, mbd, instanceWrapper)  给任何实例化的后置处理器修改的机会 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
     4.4.2.3  初始化bean       initializeBean(beanName, exposedObject, mbd)
     4.4.2.3.1   更改BeanNameAware/BeanClassLoaderAware/BeanFactoryAware     invokeAwareMethods(beanName, bean)
     4.4.2.3.2   执行所有getBeanPostProcessors的初始化的前置方法                applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
     4.4.2.3.3   执行bean的初始化方法                                          invokeInitMethods(beanName, wrappedBean, mbd)   ->  ((InitializingBean) bean).afterPropertiesSet()
     4.4.2.3.4   执行所有getBeanPostProcessors的初始化的后置方法                applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
     4.4.3  从bean实例中获取object,   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
     4.5 如果是多例 mbd.isPrototype()  则创建一个新的实例对象
     4.5.1  将创建中的多例bean存入ThreadLocal<Object> prototypesCurrentlyInCreation =new NamedThreadLocal<Object>中,    beforePrototypeCreation(beanName);
     4.5.2  将建bean对象                createBean(beanName, mbd, args)
     4.5.3  将bean从4.5.1中的prototypesCurrentlyInCreation移除        afterPrototypeCreation(beanName)
     4.5.5  从bean实例中获取object,   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);



     七.介绍 初始化bean的一些方法的执行顺序

     1、init-method方法,初始化bean的时候执行,可以针对某个具体的bean进行配置。init-method需要在applicationContext.xml配置文档中bean的定义里头写明。例如:<bean id="TestBean" class="nju.software.xkxt.util.TestBean" init-method="init"></bean>
        这样,当TestBean在初始化的时候会执行TestBean中定义的init方法。

     2、afterPropertiesSet方法,初始化bean的时候执行,可以针对某个具体的bean进行配置。afterPropertiesSet 必须实现 InitializingBean接口。实现 InitializingBean接口必须实现afterPropertiesSet方法。

     3、BeanPostProcessor,针对所有Spring上下文中所有的bean,可以在配置文档applicationContext.xml中配置一个BeanPostProcessor,然后对所有的bean进行一个初始化之前和之后的代理。BeanPostProcessor接口中有两个方法: postProcessBeforeInitialization和postProcessAfterInitialization。 postProcessBeforeInitialization方法在bean初始化之前执行, postProcessAfterInitialization方法在bean初始化之后执行。

        总之,afterPropertiesSet 和init-method之间的执行顺序是afterPropertiesSet 先执行,init-method 后执行。从BeanPostProcessor的作用,可以看出最先执行的是postProcessBeforeInitialization,然后是afterPropertiesSet,然后是init-method,然后是postProcessAfterInitialization。

转载于:https://my.oschina.net/u/3209651/blog/1936666

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值