spring-Ico-BeanFactory

文章目录

目录

文章目录

前言

一、功能

二、获取依赖

三、描述依赖

总结


前言

主要介绍了Beanfactory的功能和获取依赖和描述依赖的方式。


一、功能

  • Ioc Service Provider对象创建+依赖注入,AOP支持,对象生命周期管理,线程管理
  • 基础的Ioc容器,采用延迟初始化策略,实际访问对象时再创建并依赖注入
  • Spring用XmlBeanFactory实现BeanFactory,XmlBeanFactory可以帮我们利用BeanDefinitionReader去解析配置文件,只需要传入ClassPathSource即可

二、获取依赖

  • 获得依赖关系并注入的过程
    • 直接编码方式
      • 只需要DefaultListableBeanFactory当做BeanDefinitionRegistry来完成对象创建和依赖注入(手动将受管对象基本信息放入BeanDefinition实现类中,手动获得构造函数或者setter方法里的传入的依赖对象实例并注入,然后注册到BeanDefinitionRegistry),然后将这个DefaultListableBeanFactory转成BeanFactory,通过这个BeanFactory可以getbean
    • 外部文件配置(XML文件 / properties文件)
      • 代码逻辑基本一致(需要DefaultListableBeanFactory当做BeanDefinitionRegistry,作为bind函数的参数传入,用于接收受控对象的BeanDefinition)
      • BeanDefinitionReader实现类根据loadBeanDefinitions函数中传入的扫描路径,找到XML文件并解析,获得Ioc容器里的被控对象,并解析对象间的依赖关系,将被控对象信息放入BeanDefinition,然后BeanDefinition可以注册到BeanDefinitionRegistry中,完成Bean的注册和加载
    • 基于注解
      • 标注了注解@component 的类会被放入容器中统一管理
      • 标注了注解@Autowired 的属性会进行依赖注入
  • 获得依赖关系并注入的过程的各种名词解释
    • DefaultListableBeanFactory
      • 通用的BeanFactory实现类
      • 实现BeanFactory和BeanDefinitionRegistry两个接口
    • BeanFactory
      • 充当Bean注册过程的管理角色
    • BeanDefinitionRegistry
      • 完成实际的Bean注册和依赖注入工作
    • BeanDefinition
      • 每个受管的对象有一个BeanDefinition实现类(RootBeanDefinition和ChildBeanDefinition)的实例用于存取对象的必要信息
      • 客户端向BeanFactory请求对象时,通过BeanDefinition中的信息返回一个完备可用的对象实例
    • BeanDefinitionReader
      • BeanDefinitionReader实现类可以读取配置文件内容并将其中的管理对象信息放入BeanDefinition,然后BeanDefinition可以注册到作为参数传入的BeanDefinitionRegistry中,完成Bean的注册和加载
      • loadBeanDefinitions函数传入配置文件的路径,然后会自动实现受控对象信息放入BeanDefinition的过程
    • XMLBeanFactory
      • DefaultListableBeanFactory的基础上构建的简化XML配置加载,一行代码(只需要将配置文件地址作为参数传入)实现BeanDefinitionReader的过程

三、描述依赖

  • XML配置文件中的bean---通过配置文件写明白bean对象之间的依赖关系
    • bean的横向依赖关系
      (普通数据类型/实例对象)
      • 手动依赖注入
        • 构造方法注入怎么写XML
          • <constructor-arg >
        • setter方法注入怎么写XML
          • <property>
        • 可以配置在constructor或者property里面的
          • 依赖的是普通数据类型
            • value="xxx"
              • 注入一个具体值
            • list、set
              • 一个有序,一个无序
            • map、props
              • k-v类型,props的k只能是string
            • <null/>
          • 依赖的是对象
            • ref
              • ref=“xxx” 注入依赖对象的引用
              • ref local/parent/bean=“xxx” 注入的依赖对象引用有范围限定
              • idref bean=“xxx” 注入依赖对象的名字
            • bean
              • 内部bean,只能被当前所在的bean对象访问,其他与普通bean无区别
        • depands-on非显示依赖关系
      • autowire自动绑定/依赖注入
        • bytype
          • 容器里只有一个依赖类型的bean可以自动注册,否则只能手动配置
        • byname
          • 根据依赖对象的name找到容器里id与之相同的bean,完成自动注册
        • property可以设置byname和bytype两种autowire
        • constructor是bytype类型的autowire,根据传入构造方法参数的类型
      • dependency-check 依赖检查一般与autowire一起用
        • none不检查,simple检查简单数据类型依赖是否注入成功,object检查依赖对象是否注入成功,all所有依赖注入是否成功
      • lazy-init
        • beanFactory默认延迟初始化,ApplicationContext默认启动就完成初始化,可以通过lazy-init使其延迟初始化
    • bean的纵向继承关系
      • bean可以设置parent属性
      • bean可以设置abstract属性,abstract属性为true就无需配置class属性,初始化阶段不会实例化
        • 一群默认配置相同的bean可以继承一个abstract属性为true的bean,在该abstract bean里写一份默认配置,继承的bean可以继承这些默认配置
        • Aplicationcontext里不想初始就实例化的bean,可以设置其abstract属性为true
    • bean的scope(作用域)
      • singleton(单例bean)
        • scope是singleton的对象在Ioc容器里面只有一个实例,在第一次请求时会被初始化,所有该对象的引用共享一个实例,该实例会一直存活到容器退出,和Ioc容器几乎有着相同时间的寿命
        • 单例bean模式保证同一个Ioc容器里只保持一个bean实例对象,所有bean依赖共享这个实例,可以有好多个bean但是这些bean都依赖一个实例
        • 单例模式(保证在一个classloader中只存在一个这种类型的实例,一个类只有一个对象),实现方式
          • 饿汉式
            • 类装载时就完成实例化--没有lazy init
              • 对象设为静态常量
              • 静态代码块里创建实例)
          • 懒汉式
            • 线程不安全
              • 单线程时判断没有对象则创建
              • 同步代码块里判断没有对象就创建
            • 线程安全
              • 同步加锁只允许一个线程创建,效率低
              • 双重检查,先检查一次对象为空,再上锁并检查一次对象为空才创建
          • 静态内部类
            • 和饿汉一样,装载阶段实例化,
            • 但是只有实例化时才装载实例对象,实现了lazy-init
          • 枚举
            • 避免多线程同步的同时,防止反序列化创建新对象
      • prototype(原型/多例bean)
        • 每一次请求都由Ioc容器创建一个新的实例对象,然后交给请求方,Ioc容器不再持有这个实例的引用,该实例对象存活周期由请求方自行管理
      • 只能在web应用中使用的scope,只在XmlWebApplicationContext中使用
        • request
          • 每一个请求创建一个新的请求对象RequestProcessor对象实例,类似prototype,请求结束,该对象生命周期就结束了
        • session
          • 每个用户登录信息会放到session中,每一个session会创建一个新的UserPreferences对象实例,比request scope活的久一点
        • global session
          • 只在portlet的web应用程序中有意义,还是一个UserPreferences实例对象,和session差不多
      • 自定义scope
        • 自定义scope通过实现scope接口,并且实现其get和remove方法,注册该scope后可以供bean使用
        • scope的注册方式
          • 直接编码注册scope
            • 直接编码通过ConfigurableBeanFactory的registerScope注册自定义的scope供bean使用
          • 写在xml配置文件,bean工厂统一注册
            • BeanFactoryPostProcessor可以实现自定义scope的统一注册
            • ApplicationContext可以自动识别BeanFactoryPostProcessor
            • 可以直接在配置文件里通过class类型为CustomScopeConfigurer的bean来统一注册所有自定义scope
    • bean依赖接口--工厂方法/FactoryBean
      依赖工厂方法,由他完成接口实现类的创建
      • 如果bean依赖接口,必须将bean与接口实现类相关联
        • 自己开发只需要,自定义写接口实现类,并在bean里依赖注入接口实现类
        • 依赖第三方接口,不适合自己写接口实现类,通过工厂方法实现接口实现类,依赖工厂方法获取它创造出来的接口实现类
      • 静态工厂方法
        • <bean id="xx" class="...StaticxxInterfaceFactory" factory-method="getInstance"/>
          从class指定的静态工厂里面,通过factory-method对应的方法,取出接口实现类,作为id为xx的bean注入
        • <constructor -arg> <ref bean="xxx"> </constructor -arg>
          若构造实例的方法需要传入参数,通过constructor为工厂方法里的构造实例函数传入xxx依赖(不是传入工厂的构造函数)
      • 非静态工厂方法
        • <bean id="xx" class="...StaticxxInterfaceFactory"/>
          将工厂作为一个普通bean依赖注入
        • <bean id="xx" factory-bean="xxFactory" factory-method="getInstance"/>
          factory-bean指明一个工厂实例,在工厂实例里面通过factory-method获得接口实现类,作为id=xx的bean注入
        • <constructor -arg> <ref bean="xxx"> </constructor -arg>
          构造实例方法参数的传入
      • FactoryBean
        • FactoryBean本身是一个被注入Ioc容器(BeanFactory)的一个有点特殊的bean,用来创造容器中依赖接口的bean所依赖的接口实现类
        • XML文件配置将自定义的工厂方法注入写起来很麻烦(先注入工厂,再通过工厂实例找到方法,方法里面创建实例对象),直接实现FactoryBean接口,在FactoryBean实现类里面写对象实例化逻辑代码,然后将这个FactoryBean实现类作为一个普通的bean注入Ioc容器(beanFactory),可以由它来完成接口实现类创建
        • 将FactoryBean注入容器以后,依赖接口的bean和依赖普通对象的bean写法没有任何区别,直接通过id在factorybean里面拿到接口实现类实例
          如果是自定义工厂方法,需要在bean里面先注入工厂方法依赖,然后先拿到通过工厂方法实现类,在里面找到生成实例对象的方法,然后拿到这个方法创建的接口实现类实例,无法直接拿到接口实现类对象
        • 直接通过getBean(id)拿到的是接口实现类对象,想拿工厂FactoryBean可以通过&符号,getBean(&id)
    • bean的方法替换
      • 方法里创建一个新的依赖对象替换旧的对象
        • 场景
          • 一个类中有一个变量是一个对象,同时有一个方法可以获得该对象,想要实现每次通过方法获得对象时拿到的都是新创建的对象
            将被依赖的对象scope设置为prototype无法实现,只有第一次getbean实例化类对象的时候,容器会帮我们依赖注入一次这个被依赖的对象,而后这个类一直持有第一次创建的该对象,每次调用方法获得这个对象时,拿到的都是同一个
        • 方法注入<lookup-method>
          • <lookup-method name="xxx" bean="aaa"/>
            在配置类时,通过lookup-method实现在每次调用xxx方法时,通过Cglib动态生成一个子类aaa替代当前对象
        • BeanFactoryAware接口
          • 满足每次调用方法时都去getbean获得新的依赖对象(prototype类型保证每次getbean创建新的对象),也可以实现上述功能
          • 让类实现BeanFactoryAware接口,这样容器拿到该类的bean定义后,会将容器本身注入到这个类,类可以通过拥有一个私有beanfactory成员,然后在调用方法时通过beanfactory去调用getbean方法,保证每次拿到新的依赖对象
        • 注入ObjectFactoryCreatingFactoryBean
          • 是FactoryBean的一个实现,返回一个ObjectFactory实例,它可以为我们创建容器管理的相关对象,避免了客户端对象对beanfactory的直接引用
          • ObjectFactoryCreatingFactoryBean实现了BeanFactoryAware接口,返回的ObjectFactory是有限制条件的beanfactory,只可以通过她创造容器中的某个特定被控对象实例,不能用容器做其他事
          • 只需要在类里面定义一个ObjectFactory的成员,在配置文件里面注入ObjectFactoryCreatingFactoryBean,并指明其创建的objectfactory可以创建的被控对象类型即可
      • 创建新的方法逻辑覆盖旧的方法逻辑
        • 方法替换<replaced-method>
          • 写一个MethodReplacer实现类,在里面写需要替换的方法逻辑,注入到容器里,创建其实例对象xx
          • 在配置文件里,在需要替换方法的类的bean定义中通过<replaced-method name=“aa” replacer=“xx”>将aa方法替换为xx


总结

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值