zoukankan      html  css  js  c++  java
  • spring源码-导读与进阶

    源码读了很多次,总有些地方记得不清楚,每次用到的时候总是要从根目录找下去,这篇文章主要使用层级结构记录spring中主要类以及使用的具体位置,方便查找与理解

    一、Spring 源码流程的整体过程

    obtainFreshBeanFactory->
                beanDefinitionReader,   documentLoader 读取配置文件
                parseBeanDefinitions->
                                        parseDefaultElement->alias、beans、
                                                import(resource , 重新加载配置文件的逻辑)
                                                bean(singleton,scope , abstract , lazy-init,autowire  , depends-on , autowire-candidate,primary  , init-method , destroy-method , factory-method , factory-bean )
                                                    meta标签,lookup-method、replaced-method、constructor-arg、property、qualifier、
                                          parseCustomElement  ->   根据加载的SPI机制对应的信息进行信息加载
                最后生成:BeanDefinitionHolder(beanDefinition, beanName, aliasesArray)
      

    当含有component-scan配置中含有(annotation-config)的时候就会注册:

    ComponentScanBeanDefinitionParser 
            -> registerComponents
          ->  AnnotationConfigUtils->
                    ConfigurationClassPostProcessor
                            ->registerAnnotationConfigProcessors
                                ->postProcessBeanDefinitionRegistry
                               ->processConfigBeanDefinitions
                               ->isFullConfigurationClass()
                                        ->isFullConfigurationCandidate(判断类中是否存在Configuration注解
                                        ->isLiteConfigurationCandidate(判断类中是否有:Component,ComponentScan ,Import ,ImportResource,Bean对应注解 )
                                        -> 只要存在上面对应配置注解则BeanDefinition设置对应的标识
                                               ->PropertySources(资源文件加载,并处理变量)
                                                ->ComponentScans (扫描注解)
                                                ->Import (循环不断加载Import对应的类) 
                                                                        ->如果类上有ImportSelector则 实例化ImportSelector->执行selector.selectImports-> 然后重复执行这个引入过程 processImports
                                                                         如果是:ImportBeanDefinitionRegistrar,则注册到ConfigrationClass的类的集合中 (最终都会放到这个集合里面)   
                                                                         否则,当做一般的Configuration来处理(正常解析内部的方法如带有Bean注解的方法),
                                                                         那parse方法过后通过this.reader.loadBeanDefinitions统一将所有的ImportBeanDefinitionRegistrar进行执行
     
                                                -> ImportResource  资源导入
                                                -> Bean 注解的方法
     
     
                        Component/PropertySources/PropertySource/ComponentScans/ImportResource
                AutowiredAnnotationBeanPostProcessor - >Autowired ->反射注入对象
                CommonAnnotationBeanPostProcessor  -> Resource/PostConstruct/PreDestroy注解处理
                EventListenerMethodProcessor-> EventListener注解处理
    DefaultEventListenerFactory 

     


    prepareBeanFactory->
                注册:ApplicationContextAwareProcessor
               EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware
                ApplicationListenerDetector->收集所有的ApplicationListener
                注册getEnvironment、systemProperties、systemEnvironment

    执行所有的Processors
         两个扩展方法,自己可以实现接口进行扩展对已经注册完成的BeanDefine进行修改和新增(
    invokeBeanDefinitionRegistryPostProcessors,
    invokeBeanFactoryPostProcessors
    )
     
     
    invokeBeanFactoryPostProcessors-> 执行前面已经注册过的Processor
            currentRegistryProcessors(存放ConfigurationClassPostProcessor)
                ConfigurationClassPostProcessor(BeanDefinitionRegistryPostProcessor子类)
                    invokeBeanDefinitionRegistryPostProcessors->processConfigBeanDefinitions-》
                        isFullConfigurationCandidate-> Configuration
                        isLiteConfigurationCandidate-> Component/ComponentScan/Import/ImportResource
                                configCandidates存放满足上面2个条件的对象(自己写的带有注解的类)
                    ConfigurationClassParser——>Component ,PropertySources,ComponentScans , ComponentScan 
                                                      ->@Import(processImports) ,selector.selectImports代码不断深入循环处理 ,如果是      ImportBeanDefinitionRegistrar则(类会放到集合中),如果是Configration则,直接注册内                                                             部的bean
                                                    ->  @ImportResource
                         
     
                               -> retrieveBeanMethodMetadata 处理Bean注解
                                                    -> 注册
            reader.loadBeanDefinitions->  执行上面扫描到的ImportBeanDefinitionRegistrar接口
     
     
    1.  判断beanFactory是否为BeanDefinitionRegistry  
    2. 循环ApplicationContext中的beanFactoryPostProcessors列表对象
    3. 查找类型为:BeanDefinitionRegistryPostProcessor的类放到registryProcessors
    4. 查找BeanFactory中的类,如果为BeanDefinitionRegistryPostProcessor则放到registryProcessors
    5. 排序执行registryProcessors集合中的对象( 主要有ConfigurationAnnotationProcessor,会扫描和处理所有的注解)
    6. 重新执行4、5步骤(步骤5中可能有添加进来的对象,这个步骤会排除4中已经执行的Processors)
    7. 再次执行4、5步骤的代码(排除已经执行的)
    8. beanFactory中获取所有类型为BeanFactoryPostProcessor的数据( EventListenerProcessor和ConfigurationAnnotationProcessor )
    9. 排除上面的ConfigurationAnnotationProcessor ,然后放到容器中
     
    registerBeanPostProcessors-所有与创建实例相关的Processor按照优先级排序,bean实例化的时候会执行
    1.  beanFactory中查到所有类型为BeanPostProcessor的数据
    2. 找到的Processor添加到beanFactory的beanPostProcessors容器中( AutowiredAnnotationProcessor, CommonAnnotationProcessor)
    3. beanFactory分别找到PriorityOrdered、Ordered、其它种类的Processors
    4. beanPostProcessors中注册所有找到的Processor

    initApplicationEventMulticaster() ->初始化applicationEventMulticaster
    registerListeners()->注册监听器,主要是将一些Listener注册到applicationEventMulticaster中
      

    finishBeanFactoryInitialization - 初始化所有非懒加载的 单例对象 ->preInstantiateSingletons
                 ->   getBean -> doGetBean
    1.  查询 对象singletonObjects   中是否已经存在
    2. singletonsCurrentlyInCreation 中是否存在
    3. prototypesCurrentlyInCreation 对象中是否存在
    4. 判断当前类是否有父类,并且包含在BeanDefinition中
    5. 判断如果没有在alreadyCreated中,则mergedBeanDefinitions中删除,alreadyCreated中添加
    6. 判断是否为单例-一下是单例的创建步骤
    7. getSingleton中判断对象是否在singletonObjects中
    8. beforeSingletonCreation,判断不在inCreationCheckExclusions并且不在singletonsCurrentlyInCreation
    9. createBean -> 
    1. resolveBeforeInstantiation-> 对象创建前创建代理
    2. doCreateBean ->  populateBean initializeBean(aop的入口)
    • createBeanInstance -> obtainFromSupplier、instantiateUsingFactoryMethod(工厂方法)、autowireConstructor(autowire修饰的构造函数)、instantiateBean(无参构造函数)
    • 执行MergedBeanDefinitionPostProcessors-> applyMergedBeanDefinitionPostProcessors->postProcessMergedBeanDefinition主要包括 CommonAnnotationBeanPostProcessor(查找所有Resource注解修饰的方法和属性)、 AutowiredAnnotationBeanPostProcessor(查找类中Autowired字段和方法)、InitDestroyAnnotationBeanPostProcessor( @PostConstruct、 @PreDestory等,作用收集信息
    • populateBean参数注入->
    1. autowire现根据名称在根据类型注入
    2. 执行InstantiationAwareBeanPostProcessor主要是对属性Value的注入
    • initializeBean初始化Bean对象
    1. 初始对象执行applyBeanPostProcessorsBeforeInitialization            
    2. 如果实现了接口InitializingBean,则执行对应会方法(对象创建以后调用实现这个接口的方法)
    3. 执行初始化方法:invokeCustomInitMethod( 注解上配置的的init方法 )
    4. 执行所有初始化方法后需要执行的PostProcessor-> applyBeanPostProcessorsAfterInitialization(动态代理的Processor会执行),代理条件:引入AbstractAutoProxyCreator类的子类则会走到代理入口
    • 从三个缓存中获取数据对象:singletonObjects、earlySingletonObjects、singletonFactories
    • 注册类的销毁方法:registerDisposableBeanIfNecessary
     
    1. 判断对象是否为mbd.isPrototype
    2. doCreateBean创建一个bean
    3.  新创建的对象放到ThreadLocal中
    4. 如果不是单例,也不是prototype类型的则可能是自定义scope(可以自定义Scope,然后实现里面的创建类的工厂)
     
                
     
    创建类的动态代理
    @EnableAspectJAutoProxy-> 
                @Import(AspectJAutoProxyRegistrar.class)->执行类中的registerBeanDefinitions
                ->AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary
                ->AnnotationAwareAspectJAutoProxyCreator注册到BeanDefinitionRegistry
                ->proxyTargetClass/exposeProxy两个属性
     
    Bean创建成功->initializeBean(初始化bean)-> applyBeanPostProcessorsAfterInitialization
                        
    1.  ->processor.postProcessAfterInitialization
    1. (如果启动了AspectJ则会执行AbstractAutoProxyCreator中的方法)
    2. 如果启用了事务则会执行:AbstractAutoProxyCreator.postProcessAfterInitialization(代理入口)
    3. 查找该bean对应的advice-> getAdvicesAndAdvisorsForBean->findEligibleAdvisors->findCandidateAdvisors(实现了Advisor接口的类,其中事务就有自己的这个类)->findAdvisorsThatCanApply(查找匹配当前对象的Advisor,根据配置的信息)
    4. 创建代理工厂ProxyFactory(ProxyConfig的子类)
    •    wrapIfNecessary  -> createProxy
    •  buildAdvisors 构建Advisor集合
    • proxyFactory 创建代理工厂对象,并将Advisor和代理对象添加到proxyFactory中
    • proxyFactory.getProxy 得到代理对象
    • proxyFactory-> createAopProxy->主要是创建InvocationHandler对象
    1.  拿到DefaultAopProxyFactory,
    2.  调用createAopProxy(this),参数this为proxyFactory的父类AdvisedSupport 
    3. 创建JdkDynamicAopProxy对象(实现了InvocationHandler)
    • 创建代理对象JdkDynamicAopProxy.getProxy(classLoader)()
    1. 获取对象的接口列表proxiedInterfaces
    2. 创建代理对象:Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)
    1.  得到代理类
    2. 得到InvocationHandler为参数的构造函数
    3. cons.newInstance(new Object[]{h}),参数为实际的InvocationHandler对象
     
     
     
    如果是JDK动态代理,则在真实调用的时候会调用到JdkDynamicAopProxy中的invoke方法:
    1.  根据方法和类查找拦截器链   advised.getInterceptorsAndDynamicInterceptionAdvice
    2. 封装拦截器类对象等信息  MethodInvocation invocation = new ReflectiveMethodInvocation
    3. 执行 拦截器链retVal = invocation.proceed();
    4. 执行ReflectiveMethodInvocation 里面  dm.interceptor.invoke(this);即执行对应的拦截器(如:TransactionInterceptor,Aop相关拦截器,缓存拦截器)
    5.  
     
     
     
    二、源码中主要的接口使用
     
    1)ApplicationContextAwareProcessor类中处理Aware接口进行处理
           ApplicationContextAware 会设置applicationContext对象
           EnvironmentAware 类会收到Environment对象
           EmbeddedValueResolverAware 类会收到StringValueResolver对象
           ResourceLoaderAware 会收到ResourceLoader对象
           ApplicationEventPublisherAware 会收到ApplicationEventPublisher对象
           MessageSourceAware会收到MessageSource对象
        2)ApplicationListenerDetectorApplicationListenerDetector类会收集所有的ApplicationListener对象
     
    InitializingBean->对象创建以后会调用这个类的方法
     
     
     
    三、主要的扩展接口认识
     
     
    四、注解方式的加载流程
    1.  创建  AnnotatedBeanDefinitionReader
    2. 创建  ClassPathBeanDefinitionScanner -> doScan,注册所有的BeanDefinitio
    3. registerAnnotationConfigProcessors 注册Processors
    1. ConfigurationClassPostProcessor/AutowiredAnnotationBeanPostProcessor
    2. CommonAnnotationBeanPostProcessor
    3. DefaultEventListenerFactory
    •  refresh方法-同xml处理一样
     
    五、事务注解
    1.  @EnableTransactionManagement (这个注解在执行ConfigBeanPosProcessor时候执行的)
    2. 导入 TransactionManagementConfigurationSelector -> 执行selectImports
    3. AutoProxyRegistrar ->registerBeanDefinitions->registerAutoProxyCreatorIfNecessary->注册InfrastructureAdvisorAutoProxyCreator(对象创建以后,使用这个进行创建对象的代理,父类为AbstractAutoProxyCreator)
    4. ProxyTransactionManagementConfiguration  -> 主要实例化:(TransactionInterceptor拦截后执行哪些代码、PointCutAdvisor主要拦截过滤)
     
     
        事务代理创建流程:
    1.      bean创建完成->initializeBean(初始化方法)->applyBeanPostProcessorsAfterInitialization(执行后置处理)->processor.postProcessAfterInitialization
    2. AbstractAutoProxyCreator.postProcessAfterInitialization(子类InfrastructureAdvisorAutoProxyCreator被注册)
    3. wrapIfNecessary(对象,bean名称,缓存的key)对象包装(创建代理)
    4. getAdvicesAndAdvisorsForBean(找到所有advisor然后进行过滤-这里包括事务注解注册的PointCutAdvisor,然后满足当前对象需要的advisor)
    5. createProxy->buildAdvisors(独有的Advisor+common的Advisor)
    6. createAopProxy()->JdkDynamicAopProxy(config)(实现了InvocationHandler,并且内部持有Advisor)
    7. AopProxyUtils.completeProxiedInterfaces 查找对应的接口
    8. Proxy.newProxyInstance
    1. 使用InvocationHandler构建构造函数
    2. 使用InvocationHandler对象为参数来创建对象
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    bzoj3816 矩阵变换
    bzoj5029 贴小广告
    【BZOJ-1208】宠物收养所 Splay
    【BZOJ-2879】美食节 最小费用最大流 + 动态建图
    【BZOJ-1984】月下“毛景树” 树链剖分
    写在SDOI2016Round1前的To Do List
    BZOJ solve 100 纪念
    BZOJ-1143&&BZOJ-2718 祭祀river&&毕业旅行 最长反链(Floyed传递闭包+二分图匹配)
    【SDOI2009】解题汇总
    BZOJ-1879 Bill的挑战 状态压缩DP
  • 原文地址:https://www.cnblogs.com/lean-blog/p/14151065.html
Copyright © 2011-2022 走看看