美文网首页
Spring-Beans

Spring-Beans

作者: begonia_rich | 来源:发表于2019-08-27 02:54 被阅读0次

    spring-beans模块笔记 整理了关键接口和实现类,部分常用注解和一些流程说明


    核心接口

    BeanFactory-顶层Bean工厂接口.主要提供getBean方法

    -ListableBeanFactory-对BeanFactory接口的增强.增加了很多getBeanXXX_By_XXX方法
    
    -HierarchicalBeanFactory-对BeanFactory接口的增强.可以设置parent的BeanFactory
    
       --ConfigurableBeanFactory-接入可配置的选项.主要是内部框架使用时的设置拓展对象   
    
    -AutowireCapableBeanFactory-对BeanFactory接口的增强.增加了实例的依赖解析/注入相关api
    
           ---ConfigurableListableBeanFactory-对BeanFactory以及几个增强能力的聚合接口,代码中不推荐使用应当根据需要使用真实的接口
    

    这几个接口是非常核心的接口,实际上容器的默认实现DefaultListableBeanFactory在继承体系中一层层的都实现了这几个接口的功能

    常见接口

    Aware-顶层标记接口,根据BeanFactory注释中说的"推送配置优于拉配置”的理念,所有bean增强的能力都是通过接口的方式推给你的,你不用自己去拉

    FactoryBean-高级组件,自定义Bean的初始化与其他配置,它的依赖应当通过构造函数或BeanFactoryAware编程式的获取

    SmartFactoryBean-支持设置早期初始化行为

    SmartInitializingSingleton-类似于InitializingBean,这是在BeanFactory完成之后的回调

    BeanDefinition-对Bean进行描述的接口,可以获取构造参数/属性值/依赖项/

    -AnnotatedBeanDefinition-对BeanDefinition接口的增强,引入了注解元信息,目前使用较多
    

    BeanFactoryPostProcessor-调整Bean定义和调整BeanFactory的配置,框架的很多特性都是通过这个接口实现的,比如BeanDefinition中的字符串占位符解析,以及更灵活的对BeanFactory的配置支持

    BeanFactoryPostProcessor用的非常多,很多高级特性实现都是基于它

    BeanReference-通过BeanName在运行期进行实际Bean实例的引用替换,在BeanDefinition阶段使用较多,因为这时候还没有Bean实例,通过这种引用来建立实际依赖的,比如它的实现类RuntimeBeanReference

    Scope-定义了Bean的范围概念,在单例和原型模式之外的Bean的生命周期如果想要控制的话(e.g:request/session)都是通过定义Scope来实现的

    ObjectFactory-内部自己用的Bean提供策略,类似于FactoryBean不过没有定义更详细的细分接口,只有一个getObject,具体规则实现类自己定

    AliasRegistry-别名注册器顶层接口,BeanFactory都要支持别名,如SimpleAliasRegistry就是简单的Map实现


    关键实现类

    BeanDefinitionVisitor-通过访问者模式对BeanDefinition中占位符进行替换

    XxxResolver-很多Resolver都是主流程的部分具体实现拆出来的,不然主流程就太长了.比如ConstructorResolver是实例化部分的实现,BeanDefinitionValueResolver是对依赖的构造函数值/方法值进行解析.RuntimeBeanReference的实现部分就在这里

    BeanFactory的继承体系

    这里的实现类介绍主要就是这里的右面继承体系中涉及的类

    SimpleAliasRegistry-顶层基类,引入AliasRegistry(别名注册器)接口,并实现部分子接口ConfigurableBeanFactory的功能

    DefaultSingletonBeanRegistry-继承SimpleAliasRegistry,引入SingletonBeanRegistry(单例Bean注册器)接口,并实现部分子接口ConfigurableBeanFactory的功能

    FactoryBeanRegistrySupport-继承DefaultSingletonBeanRegistry,主要增加一些FactoryBean注册的方法供子类调用

    AbstractBeanFactory-继承FactoryBeanRegistrySupport,引入主要配置接口ConfigurableBeanFactory,定义了getBean的流程(这里主要是递归加载依赖Bean,优先处理单例和原型,最后根据scope自定义范围)以及一些抽象方法(如createBean)让子类实现

    AbstractAutowireCapableBeanFactory-继承AbstractBeanFactory,引入自动装载拓展接口AutowireCapableBeanFactory.主要定义了createBean流程,它主要是创建Bean,初始化Bean

    DefaultListableBeanFactory-继承自AbstractAutowireCapableBeanFactory,引入进一步增强的三合一接口ConfigurableListableBeanFactory和BeanDefinitionRegistry

    可以看到这里在继承体系中逐步的拆解了几个核心接口的功能,不过很多接口的实现都很特别,通过实现类与接口平行的结构进行实现,随后在子类中通过继承与接口实现再合并.


    BeanFactory核心方法

    registerBeanDefinition(提供外部注册bean定义)

    getBean(最常用的接口.实际上此接口只负责分区域加载,不负责具体创建)

    createBean(核心实例化,初始化流程.可选自动注入类型等)

    createBean和getBean的流程是互相嵌套递归.getBean的时候需要自己对依赖getBean到最后还需要创建Bean,创建Bean的时候需要对初始化依赖的参数再getBean.最终解开层层嵌套,进而创建无依赖的Bean(环形的属性依赖会使用占位符先解开依赖问题)

    理解这几句话对创建Bean的流程有很大的帮助

    环形依赖问题:环形依赖可能出现在单例中的构造函数互相依赖或者原型模式中的属性依赖,如果只是单例属性依赖的话不会造成环形依赖.


    创建Bean时的部分生命周期回调

    BeanPostProcessor-调整Bean实例,甚至可以替换,大多数情况使用这个进行创建Bean的代理来拓展一些Bean行为.这是在初始化前后的回调

    BeanPostProcessor用的也非常多,简单的加代理行为基本都是通过它实现

    InstantiationAwareBeanPostProcessor-在bean实例化前后进行回调也就是Class --> Bean这个转换过程以及初始化之前,主要是决定替换代理的

    MergedBeanDefinitionPostProcessor-在实例化之后与初始化之前的回调.可以解析BeanDefinition,比如说AutowiredAnnotationBeanPostProcessor就是在这里实现的解析需要注入的属性放入缓存中,以便在后面直接使用


    createBean生命周期的回调接口顺序

    1.InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation实例化之前进行调用,如果返回空,会直接调用BeanPostProcessor.postProcessAfterInitialization方法进行初始化前置.如果返回了自定义的Bean,那么不会进行属性注入.直接返回

    2.MergedBeanDefinitionPostProcessor实例化之后的回调,可以对BeanDefinition进行信息获取

    3.InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation属性注入分析之前进行调用.这里主要是给与使用者自己进行注入的机会,一旦自己进行属性配置,那么将不会进行属性解析

    4初始化
    4.1先调用Aware方法注入,BeanNameAware,BeanClassLoaderAware,BeanFactoryAware等

    4.2调用BeanPostProcessor执行前置方法postProcessBeforeInitialization

    4.3调用afterPropertiesSet或自定义初始化方法

    4.4最后调用BeanPostProcessor执行后置方法postProcessAfterInitialization结束初始化


    createBean方法注入流程

    AutowireByType流程

    1先处理@Value注解

    2处理容器类型,Array,Collection,Map类型

    3处理同类型多个Bean,@Primary 先获取,其次@Order 排序较高的再处理

    4最后如果要求注入的类型非容器类型,而且必须要求注入,那么直接报错没找到类

    AutowireByName流程

    直接通过属性名调用getBean方法获取bean,注入属性中,没找到直接报错


    关键注解功能描述

    @Autowired-自动注入.其还可以支持注入Collection和Map(key-beanName,value-Bean),Array类型的属性

    @Qualifier-多个类型相同的Bean,进行@Autowired时对beanName的进一步限制,支持自定义新的限定注解

    @Value-注入SPEL表达式

    @Lookup-以注解的方式在方法级解决原型模式对象依赖的问题

    @Required-标记依赖为必须项

    @Configurable-非Spring管理的容器,获取自动装配能力


    FactoryBean在beans包中的使用

    Spring提供了很多很有用的FactoryBean,是为了在声明Bean时尽可能的提供更灵活的方式,这里看下

    AbstractFactoryBean<T>:实现了FactoryBean的简单模板超类,它根据标志来决定是创建一个单例还是一个prototype对象。

    FieldRetrievingFactoryBean:静态方法或普通方法的调用转换

    ListFactoryBean:声明一个List作为Bean

    MapFactoryBean:声明一个Map作为Bean

    SetFactoryBean:声明一个Set作为Bean

    MethodInvokingFactoryBean:用以指定方法调用的返回值作为一个Bean

    ObjectFactoryCreatingFactoryBean:返回一个ObjectFactory包装的对象,它通过beanName从容器get对象

    PropertiesFactoryBean:它支持从classpath位置的文件中读取配置对象作为实例返回

    PropertyPathFactoryBean:通过指定的bean,以及指定的属性作为一个Bean对象

    ProviderCreatingFactoryBean:返回一个Provider包装的对象,它通过beanName从容器get对象

    ServiceLocatorFactoryBean:一般在注入属性需要原型模式时使用,通过反射每次获取对象时确保为新对象

    ServiceFactoryBean-适配ServiceLoader获取第一个Service作为一个Bean对象

    ServiceListFactoryBean-适配ServiceLoader获取所有的Service作为一个Bean对象

    ServiceLoaderFactoryBean-直接返回ServiceLoader作为一个Bean对象


    BeanFactoryPostProcessor在beans包中自身的特性实现

    ConfigurationClassPostProcessor-引导配置解析的核心类,非常重要,这是context包的内容这里不细说

    PlaceholderConfigurerSupport-将所有的BeanDefinition中的占位符(${})进行了替换

    CustomScopeConfigurer-允许自定义的Scope注册

    CustomAutowireConfigurer-允许自定义的@Qualifier限定注解注册

    CustomEditorConfigurer-允许自定义的PropertyEditor注册

    DeprecatedBeanWarner-检测一下@Deprecated弃用注解,匹配的话日志警告一下


    标准Bean生命周期接口以及完整的初始化方法及其标准顺序

    自上向下依次为:
    创建时
    BeanNameAware's {@code setBeanName}

    BeanClassLoaderAware's {@code setBeanClassLoader}

    BeanFactoryAware's {@code setBeanFactory}

    EnvironmentAware's {@code setEnvironment}

    EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}

    ResourceLoaderAware's {@code setResourceLoader}

    ApplicationEventPublisherAware's {@code setApplicationEventPublisher}

    MessageSourceAware's {@code setMessageSource}

    ApplicationContextAware's {@code setApplicationContext}

    ServletContextAware's {@code setServletContext}

    {@code postProcessBeforeInitialization} methods of BeanPostProcessors

    InitializingBean's {@code afterPropertiesSet}

    a custom init-method definition

    {@code postProcessAfterInitialization} methods of BeanPostProcessors

    关闭时

    {@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors

    DisposableBean's {@code destroy}

    a custom destroy-method definition

    Aware部分实现在context包的ApplicationContextAwareProcessor中,它是一个BeanPostProcessor

    beans包中主要实现了在类初始化前后的回调,以及创建/初始化等也就是BeanPostProcessor,InitializingBean.其他的Aware都是基于此进行的拓展

    已经标出了常用的一些接口,这里能看到可以获取的Aware配置也能看到他们的顺序


    总结

    1整个beans包的类非常的多,之前接触的很多特性实现都是在这个包内实现的

    2很多接口声名的很简单,在实现类中很多public方法是子接口声名的,既没有在原顶层接口增加新方法,又保持了各个接口实现的独立性,可以借鉴下

    3实现一个复杂流程可以采用XxxResolver将部分流程委托出去进行处理,如果需要内部一些方法将自己也传出去

    4在建立自定义流程时需要增加自己的特性,可以采用包装类的方式在实现时进行类型判断处理.比如RuntimeBeanReference,ManagedList等

    相关文章

      网友评论

          本文标题:Spring-Beans

          本文链接:https://www.haomeiwen.com/subject/udzjectx.html