Spring Bean 相关概念整理

Spring Bean 相关概念


  • IoC

    使用对象的时候,直接new一个对象,使得当前模块与new的对象耦合了,这与面向接口面向抽象编程相冲突,也带来了系统模块架构问题。

    比如,调用dao层的时候,在使用的时候,会new一个特定数据库的dap层,这与特定数据库绑定了;如果采用抽象工厂来获取dao的实现类,在工厂类中需要把所有数据库的dao写出,在数据库迁移的时候,需要修改这个工厂类。

    采用IoC之后,通过容器自动为业务层设置dao的实现类,可以在不修改代码的情况下,实现数据库换库迁移。实现了松耦合。

    在spring的bean定义文件中,可以定义bean设置属性,bean之间的继承,bean的抽象和不同的获取方式。

  • Bean容器初始化

    1.beans包

    BeanFactory类以及子类 加载并初始化bean

    使用工厂模式来获取bean,有静态工厂模式和实例工厂模式,在配置中有所区别。

    静态工厂

    调用TestFactory的getBean()方法来获取bean,而且TestFactory是没有实例化的,所以获取的时候,通过静态方法

    <bean id="bean_string" class="com.qtone.test.TestFactory" factory-method="getBean"/> 

    对应的实际代码

    public static Object getBean() 
    { 
      ...//Remainder omitted 
    } 

    实例工厂

    先实例化一个DalDataSourceFactory,再根据这个实例来调用createDataSource方法进行初始化

    <bean id="dalDatasourceFactory" class="com.datasource.configure.DalDataSourceFactory"/>
    
    <bean id="datasourcesDB" factory-bean="dalDatasourceFactory"
        factory-method="createDataSource">
          <constructor-arg name="allInOneKey" value="***" />
          <constructor-arg name="svcUrl" value="*****"  />
    bean>

    对应的实际代码

    public DatasourcesDB createDataSource(String allInOneKey, String svcUrl) 
    { 
      ...//Remainder omitted 
    }

    2.context包

    ApplicationContext 保存bean对象

    spring的容器,与beanFactory类似,可以加载配置文件中定义的bean,集中bean,在有请求的时候分配bean,另外,还增加了企业需要的功能。比如,属性文件解析文本信息,将事件传递给所指定的监听器。

    常用ApplicationContext 接口实现,用于加载已被定义的bean:

    FileSystemXmlApplicationContext 提供xml文件的完整路径

    ClassPathXmlApplicationContext 不需xml文件的完整路径,只需配置正确的classpath环境变量

    WebXmlApplicationContext 不需xml文件的完整路径,在一个web应用程序范围内加载

    利用ClassPathXmlApplicationContext去生成工厂Bean,生成和初始化所有对象

    protected void configure(final HostConfig hostConfig) {
          ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring-config.xml");
          initializeSpring(applicationContext);
          HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
    }

    3.两者的区别

    ApplicationContext能以声明的方式创建,如使用ContextLoader,而BeanFactory只能用变成的方式创建。

    ContextLoader有两个实现,ContextLoaderListenerContextLoaderServlet,两者功能相同,两者的差异为对于Servlet规范的兼容性的区别,推荐ContextLoaderListenerContextLoaderListener需要检查contextConfigLocation参数,按照预先定义的分隔符进行字符串的分割,并将这些值作为应用上下文的搜索位置,如果不存在的话,它将默认使用/WEB-INF/applicationContext.xml

    ApplicationContext在容器启动时,一次性加载所有的bean,可以在容器启动时,就发现存在的配置错误。BeanFactory是延迟加载形式来注入bean,只在getBean()的时候,才对bean进行加载实例化。

    ApplicationContext可以加载多个Resource,扩展了ResourceLoader接口,而BeanFactory没有。

    ApplicationContext支持国际化,利用MessageSource接口,而BeanFactory没有。

    ApplicationContext事件传播机制,即当ApplicationContext中发布一个事件的时,所有扩展了ApplicationListener的Bean都将会接收到这个事件,并进行相应的处理。主要通过ApplicationEvent和ApplicationListener两个接口来提供,如果需要自己来扩展spring中的事务,需要实现ApplicationEvent接口。

  • Spring注入

    启动spring容器加载bean配置,完成对变量的赋值行为

    1.设值注入 自动调用set方法对属性赋值

  <bean id="personDao" class="cn.glzaction.service.impl.PersonDaoBean">
    <property name="name" type="java.lang.String" value="glzaction"/>
    <property name="id" type="java.lang.Integer" value="1"/>
    <property name="list" type="java.util.List">
        <list>
            <value>list1value>
            <value>list2value>
            <value>list3value>
        list>
    property>
    <property name="map" type="java.util.Map">
        <map>
            <entry key="key1" value="value1">entry>
            <entry key="key2" value="value2">entry>
        map>
    property>
bean>

如果要使用设值注入,域不能为基本类型,要用其对应的包装类型进行替换。只能注入自定义类或者包装类型。

spring的设值注入,采用property标签,name是注入变量名称,type是注入变量类型,value对应初始值。

还有一种ref,对应bean的名称,如果注入的是bean,就要用ref而不是value。

<bean id="DB" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasourcesDB"/>
        <property name="typeAliasesPackage" value="***"/>
        <property name="mapperLocations" value="classpath*:mapper/*Mapper.xml"/>
 bean>

2.构造注入 自动调用构造器进行赋值

<bean id="personDao" class="cn.glzaction.service.impl.PersonDaoBean">bean >


<bean id="personService" class="cn.glzaction.service.impl.PersonServiceBean">
    <constructor-arg index="0" type="cn.glzaction.service.impl.PersonDaoBean" ref="personDao"/>
    <constructor-arg index="1" type="java.lang.String" value="glzaction"/>
    <constructor-arg index="2" type="java.util.List">
        <list>
            <value>list1value>
            <value>list2value>
            <value>list3value>
        list>
    constructor-arg>
bean>

spring的构造注入,采用constructor-arg标签,index是设定参数在构造器中的索引顺序,可选,但是推荐写明参数的位置,利于spring的构造,以后后续查看直观清晰。

type为注入变量的类型,value为注入的值,ref为注入的bean。

  • Bean配置

    id

    class bean对应具体哪一个类(必须)

    scope

    constructor arguments

    properties

    autowire

    默认不启动自动装配,有几种模式no、byName、byType、constructor、autodetect、default

    lazy-init 延迟初始化,将在第一次被用到的时候实例化

    init-method/destroy-method

    示例如下

    <bean id = "mybean" Class = "com.spring.MyBean"
          Singleton = "false"
          init-method = "initMethod"
          destroy-method = "destroyMethod"
          autowire = "autowire type"
          lazy-init="true"
      />

  • Bean作用域

    1.singleton 一个bean容器只存在一份(default)

    2.prototype 每次请求会创建新的实例,并且destroy方式不生效

    3.request 每次http请求会创建新的实例,且仅在当前request内有效

    4.session 类似,当前session内有效

    5.global session 基于portlet的web中有效,如果是在web中,同session

  • Bean生命周期

    1.定义 xml中配置id、class等信息

    2.初始化

    3.使用 从容器中取出并使用

    4.销毁 在容器停止时,销毁bean容器创建的实例

    初始化,实现InitalizingBean接口,覆盖afterPropertiesSet方法,配置init-method在xml中

    销毁,实现DisposableBean接口,覆盖destroy方法,配置destroy-method在xml中

你可能感兴趣的:(spring,Java)