zoukankan      html  css  js  c++  java
  • 2.Spring的Bean生命周期和组装方式

    1.Spring IoC容器概述

       Spring IoC容器: 

        Spring容器即体现了IoC原理
        Spring容器通过读取配置元数据负责对Beans实例化、配置和装配
         配置元数据可以用XML、Java注解或Java代码来描述

         org.springframework.beans和org.springframework.context包是Spring框架IoC容器的基础

    BeanFactory:

    BeanFactory提供了一个先进的配置机制能够管理任何类型的对象
    BeanFactory负责对Bean对象的实例化、装配和生命周期的管理
    BeanFactory的实现:
    XmlBeanFactory
    创建该工厂需要传入一个Resource实例,例如ClassPathResource或者FileSystemResource等
    BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
    从BeanFactory获取Bean实例
    MyBean bean = (MyBean)factory.getBean("myBean")

     ApplicationContext:

    ApplicationContext是BeanFactory的一个子接口
    ApplicationContext添加了更多的企业特定的功能:
    例如增加了更方便的集成Spring的AOP功能
    消息资源处理(用于国际化)
    事件的发布
    ApplicationContext的实现:
    ClassPathXmlApplicationContext
    FileSystemXmlApplicationContext
    XmlWebApplicationContext
    AnnotationConfigApplicationContext

    两者区别:

    BeanFactory提供了配置框架和基本功能,ApplicationContext则添加了更多的企业特定功能
    ApplicationContext是BeanFactory的一个子接口,同时也是它的一个完整的超集
    实例Bean的载入方式不同:
    BeanFactory延迟载入所有Bean,直到getBean()方法调用时才被创建
    ApplicationContext启动后载入所有单实例Bean。通过预载入单实例Bean,确保当需要时可以使用。

    Spring IoC容器:

    Spring IoC容器的使用:

    配置元数据
    基于Xml的配置
    基于Annotation的配置
    基于Java的配置
    实例化容器
    使用容器

    2.Bean的概述

       Bean概念;   

    一个Spring IoC容器管理了一个或者多个beans
    这些beans通过你提供给容器的配置元数据进行创建
    Bean的实例化:
    通过构造方法实例化
    使用静态工厂方法实例化
    使用实例工厂方法实例化

       实例化Bean:

      1.通过构造方法实例化:
    当使用基于XML的元数据配置文件,可以这样来指定bean类:

     

        2.使用静态工厂方法实例化:

    当采用静态工厂方法创建bean时,除了需要指定class属性外,还需要通过factory-method属性来指定创建bean实例的工厂方法
    注意,此定义并未指定返回对象的类型,仅指定该类包含的工厂方法,此例中createInstance方法必须是静态的。

        3.使用实例工厂方法实例化:

    使用实例工厂方法实例化:
    使用这种方式时,class属性必须为空,而factory-bean属性必须指定为当前(或其祖先)容器中包含工厂方法的bean的名称
    bean的工厂方法必须通过factory-method属性来设定

     Bean的声明周期:

     Bean作用域:

    注意事项:
    单例作用域是针对一个Spring容器一个实例,并且是Spring中Bean的默认作用域
    Spring不会管理原型作用域的完整生命周期,他只负责初始化、 配置,亦或者组装原型域的Bean对象,但是不会调用Bean的销毁方法。

    Bean的生命周期:

    步 骤

    说 明

    1.实例化

    Spring实例化Bean

    2.设置属性

    Spring注入Bean的属性

    3.设置Bean名称,Bean工厂,应用上下文

    如果Bean实现了XXXAware接口,执行对应方法

    4.预处理(在初始化之前)

    调用BeanPostProcessor对象的postProcessBeforeInitialization()方法

    5.初始化Bean

    实现InitializingBean接口的afterPropertiesSet()方法

    声明了初始化方法,将调用声明的

    6.预处理(在初始化之后)

    调用BeanPostProcessor对象的postProcessAfterInitialization()方法

    7.Bean已经准备好

    默认以单例的形式存在Spring容器中

    8.销毁Bean

    实现DisposableBean接口的destroy()方法

    声明了销毁方法,将调用声明的

    实现*Aware接口:

    有些时候我们需要在Bean的初始化中使用Spring框架自身的一些对象来执行一些操作,比如:
    获取ServletContext的一些参数
    获取ApplicaitionContext中的BeanDefinition的名字
    获取Bean在容器中的名字等等

    Spring提供了一组名为*Aware的接口,例如:
    BeanNameAware:获得Bean在配置文件中定义的名字
    BeanFactoryAware:获得BeanFactory对象,可用来检测Bean的作用域
    ApplicationContextAware: 获得ApplicationContext对象,可以用来获取所有Bean definition的名字
    ResourceLoaderAware:获得ResourceLoader对象,可以获得classpath中某个文件
    ServletContextAware:在一个MVC应用中可以获取ServletContext对象,可以读取context中的参数
    ServletConfigAware在一个MVC应用中可以获取ServletConfig对象,可以读取config中的参数

    initialization和destroy:

    有时我们需要在Bean属性设置好后和Bean销毁前做些事情,Spring提供了多种方法在Spring的Bean的生命周期中执行初始化和销毁
    实现InitializingBean和DisposableBean接口
    在bean的配置文件中制定init-method和destroy-method方法
    使用@PostConstruct和@PreDestroy注解 

    实现InitializingBean和DisposableBean接口
    该方法简单,但不推荐,因为会将Bean的实现和Spring框架耦合在一起

    在bean的配置文件中制定init-method和destroy-method方法

    3.Bean的依赖注入的

    依赖注入指对象之间的依赖关系
    Spring容器的工作就是创建Bean并注入他所依赖的Bean对象
    Spring中的注入方式主要有2种:构造器注入和Setter方法注入

     构造器注入: 

    基于构造器注入DI通过调用带参数的构造器来实现,每个参数代表着一个依赖关系
    构造器参数通过参数类型进行匹配

    我们还可以使用type属性指定构造参数的类型
    我们还可以使用index属性指定构造参数的索引
    我们还可以使用name属性制定构造参数的名字

    Setter注入

    基本Bean注入

    注入基本数据类型
    <property name="xxx" value="xxx" />
    可注入:
    字符串
    数值型数据
    布尔类型
    Spring根据字段属性来决定转换成正确的类型
    注入Null
    <property name="xxx"><null /></property>

    注入引用数据类型
    引用
    <property name="xxx" ref="xxxBean" />
    <property name="xxx"> <ref bean="xxxBean" /> </property>
    注入内部Bean
    <property name="xxx"> <bean class="org.xxx.XxxBean" /> </property>
    内部Bean不能复用,只能被注入

    注入List类型和数组类型
    对应的Java类型是:List和Array
    <property name=“xxx”> <list> <ref bean=“aa” /> <ref bean=“bb” /> <value>aaa</value> <value>bbb</value> </list> </property>
    注入List类型和数组类型
    对应的Java类型是:List和Array
    <property name=“xxx”> <list> <ref bean=“aa” /> <ref bean=“bb” /> <value>aaa</value> <value>bbb</value> </list> </property>

    注入Set类型
    对应的Java类型是:Set
    <property name=“xxx”> <set> <ref bean =“aa” /> <ref bean =“bb” /> </set> </property>

    <set>保证其中每个元素都是唯一的

    注入Map类型
    对应的Java类型是:Map
    <property name=“xxx”> <map> <entry key=“a” value-ref=“aa” /> <entry key=“b” value-ref=“bb” /> </map> </property>
    每个<entry>都有一个键和值组成
    key: 指定map项的键为String
    key-ref: 指定map项的键为Spring上下文中其他Bean的引用
    value: 指定map项的值为String
    value-ref: 指定map项的值为Spring上下文中其他Bean的引用

    注入Properties类型
    对应的Java类型是:Properties
    <property name=“xxx”> <props> <prop key=“a”>aaa</prop> <prop key=“b”>bbb</prop> </props> </property>
    与Map唯一不同的是其限制了键和值都是String

    集合合并:

    对于相同类型的集合,
    通过在子类中的merge属性,
    可以将集合合并。

    高级Bean注入:

    Spring容器可以自动装配相互协作bean的关联关系
    自动装配有以下好处:
    自动装配可以显著得减少指定属性或者构造器参数的需求
    当对象发生变化时自动装配可以更新配置而不需要修改配置
    自动装配的局限性和缺点:
    Property和constructor-arg显示的依赖设置会覆盖自动装配(故意而为)
    自动装配没有显示编写精确
    在容器中可能存在多个bean的定义与自动装配的setter方法或者构造方法参数匹配,若bean定义不唯一,装配时会抛异常

    模板装配(声明父类Bean和子类Bean)
    指定Bean的abstract="true"
    表示<bean>声明是抽象的,不能被Spring实例化
    通常也用来表示一个“模板”<bean>,用来抽象一些共同的属性
    指定parent属性
    <bean id="aa" parent="xxxBean" />
    可以继承父Bean的属性,也会继承它的类

    使用外部属性文件:

    可以使用location属性处理单个属性文件
    <property name="location" value="jdbc.properties"/>
    处理多个属性文件用locations属性指定list
    <property name="locations"> <list> <value>aa.properties</value> <value>bb.properties</value> </list> </property>
    使用${xxx.bbb}来获取值


    可以覆盖继承的属性

      

  • 相关阅读:
    [POJ1811]Prime Test
    Pollard-rho算法[因子分解算法]
    Miller-Rabin算法
    [POJ2886]Who Gets the Most Candies?
    Failed to connect to raw.githubusercontent.com port 443
    MAC安装flutter开发环境
    Jenkins自动化打包(Gitlab)并上传蒲公英
    Jenkins中插件下载失败的解决办法
    iOS开发~防止navigation多次push一个页面
    Jenkins 更新 jenkins.war的方法
  • 原文地址:https://www.cnblogs.com/Firesun/p/9884293.html
Copyright © 2011-2022 走看看