Spring 学习笔记2—— IoC容器

-本文大部分内容来源于《SPRING攻略++第2版》学习过程-

必须实例化SpringIoC容器,读取其配置来创建bean实例,然后从Spring IoC容器中得到可用的bean实例。

Spring提供两种IoC容器实现类型。

  • Bean factory
  • Application contet
    应用程序上下文提供比Bean工厂更高级的特性,两种类型配置文件相同。

Bean工厂接口是:BeanFactory
应用程序上下文接口:ApplicationContext

ApplicationContext接口是用于保持兼容性的BeanFactory子接口。

实例化应用程序上下文

ApplicationContext仅仅是一个接口,必须实例化一个接口的实现。ClassPathXml ApplicationContext实现从classpath中装入一个XML配置文件,构建一个应用程序上下文。也可以为其指定多个配置文件。

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

除了ClassPathXmlApplicationContext,Spring还提供多种其它的ApplicationContext实现。

  • FileSystemXmlApplicationContext
  • XmlWebApplicationContet
  • XmlPortletApplicationContext

从IoC容器中得到Bean

为了从Bean工厂或者应用程序上下文中得到已声明的bean,只需要调用getBean()方法并且传递唯一的bean名称。getBean()方法的返回类型为java.lang.Object,在使用前必须将其转换为实际的类型。

SequenceGenerator generator=(SequenceGenerator)context.getBean("sequenceGenerator");

到这一步,就能像使用任何使用构造函数创建的对象一样,自由使用bean了。

配置Spring IoC容器中的Bean

Spring提供了一个强大的IoC容器来管理组成应用的bean。为了利用容器服务,必须配置运行于Spring IoC容器中的Bean。

可以通过Xml文件、属性文件、注释甚至API来配置Spring IoC容器中的Bean。
Spring允许在一个或多个bean配置文件中配置bean。对于简单的应用程序,可以在单个配置文件中集中配置bean。但对于有多个bean的大型应用,应根据功能分割到多个配置文件中。

假定开发一个生成序列号的应用程序,为不同用途生成许多系列的序列号,每个系列都有自己的前缀、后缀和初始值。因此,需要在应用程序中创建和维护多个生成器实例。

创建Bean类

按照需求,创建具有prefix、suffix和initial3个属性的SequenceGenerator类,这可以通过setter或构造函数注入。私有字段counter用于保存这个生成器的当前数值。每当在生成实例上调用getSequence()方法,都将得到加上前缀和后缀的最新序列号。将这个方法声明为同步(synchronized),使其成为线程安全的方法。

package com.apress.springprcipes.sequence;

public class SequenceGenerator {
    private String prefix;
    private String suffix;
    private int initial;
    private int counter;

    public SequenceGenerator(){}

    public SequenceGenerator(String prefix,String suffix,int initial){
        this.prefix=prefix;
        this.suffix=suffix;
        this.initial=initial;
    }

    public void setPrefix(String prefix){
        this.prefix=prefix;
    }
    public void setSuffix(String suffix){
        this.suffix=suffix;
    }
    public void setInitial(int initial){
        this.initial=initial;
    }
    public synchronized String getSequence(){
        StringBuffer buffer=new StringBuffer();
        buffer.append(prefix);
        buffer.append(initial+counter++);
        buffer.append(suffix);
        return buffer.toString();
    }
}

这个SequenceGenerator类可以由取值/设值方法或者构造函数配置。
使用容器进行配置时,这种方法被称为构造函数注入和设值方法注入。

创建Bean配置文件。

"http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/springbeans-3.0.sd">
...

在Bean配置文件中声明bean

每个bean都应该提供一个唯一的名称或者id,以及一个完全限定的类名,用来让Spring IoC容器对其进行实例化。对于简单类型的每个bean属性,可以为其指定一个元素。Spring会试图将指定的值转换为该属性的声明类型。为了通过设值方法注入配置一个属性,可以使用元素,并在其name特性中指定属性名称。每个要求bean包含对应的一个设值方法。

<bean name="sequenceGenerator"
   class="com.apress.springrecipes.sequence.SequenceGenerator">
   <property name="prefix">
      <value>30value>
   property>
   <property name="suffix">
      <value>Avalue>
   property>
   <property name="initial">
      <value>10000value>
   property>
bean>

也可以在元素中声明,通过构造函数来配置Bean属性。中没有name属性,参数是基于位置的。

<bean name=...>
   <constructor-arg><value>30value>constructor-arg>
   <constructor-arg><value>Avalue>constructor-arg>
   <constructor-arg><value>10000value>construcor-arg>
bean>

在 Spring中,如果装入了超过一个上下文,允许重复的名称覆盖Bean声明。Bean名称可由的name属性定义。但首先的方法是通过id属性。
XML在id属性有字符限制,比如不能用一些特殊字符。 name里允许用逗号,但id不允许。

Spring支持指定简单类型属性值的一个简写。如:

 <property name="prefix" value="30" />

从Spring2.0开始,添加了这样一种简写:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/springbeans-3.0.sd">
  <bean id="sequenceGenerator" class="..." p:prefix="30" p:suffix="A" p:initial="100000" />
beans>

为Bean配置集合

Java的主要集合类型:List/Set/Map。
例如 : 允许序列生成器具有超过一个后缀,这些后缀将附加在序列号后面,以连字号分隔。

package com.apress.springprcipes.sequence;

import java.util.List;

public class SequenceGenerator {
    private String prefix;
    private Listsuffixes;
    private int initial;
    private int counter;

    public SequenceGenerator(){}

    public SequenceGenerator(String prefix,String suffix,int initial){
        this.prefix=prefix;
        this.initial=initial;
    }

    public void setPrefix(String prefix){
        this.prefix=prefix;
    }
    public void setInitial(int initial){
        this.initial=initial;
    }
    public synchronized String getSequence(){
        StringBuffer buffer=new StringBuffer();
        buffer.append(prefix);
        buffer.append(initial+counter++);
        for(Object suffix:suffixes){
            buffer.append("-");
            buffer.append(suffix);
        }
        return buffer.toString();
    }

    public void setSuffixes(Listsuffixes){
        this.suffixes=suffixes;
    }
}

bean定义

<bean id="sequenceGenerator"
   class="com.apress.springrecipes.sequence.SequenceGenerator">
    <property name="initial" value="100000" />
    <property name="suffixes">
       <list>
          <value>Avalue>
          <bean class="java.net.URL">
             <constructor-arg value="http" />
             <constructor-arg value="www.apress.com" />
             <constructor-arg value="/" />
          bean>
          <null />
       list>
    property>
 bean>

另外set接口、Map、Properties详情可见原书《SPRING攻略++第2版》 P9。

合并父Bean集合

原书P12 略……

调用构造函数创建Bean

原书P14 略……

Spring IoC容器中Bean的生命周期

本部分学习资源来源于《尚硅谷 玩转JAVA系列》

Spring IoC 容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务。

Spring IoC容器中Bean的生命周期如下:

  1. 通过构造函数或工厂方法创建Bean实例:调用构造函数
  2. 为Bean的属性设置值和对其他Bean的引用:调用setter
  3. 将Bean实例传递给Bean后置处理器的postProcessBeforeInitialization方法
  4. 调用Bean的初始化方法init-method
  5. 将Bean实例传递给Bean后置处理器的postProcessAfterInitialization方法
  6. Bean可以使用了
  7. 当容器关闭时,调用Bean的销毁方法:destroy-method。

Bean的初始化和销毁方法:可以通过bean节点的init-method和destroy-method来配置Bean的初始化方法和销毁方法:

id="person" class="com.atguigu.spring.lifecycle.Person" init-method="init"
destroy-method="destroy">
   <property name="name" value="abcd">property>

ApplicationContext接口中没有关闭容器的方法,所以使用ApplicationContext接口作为IoC容器的引用,destroy-method将不会起作用,需要使用ApplicationContext的子接口ConfigurableApplicationContext。

Bean 后置处理器

  • 允许在调用初始化方法(即:bean节点init-method属性对应的方法的前后)对Bean进行额外的处理
  • Bean后置处理器对IoC容器里的所有Bean实例逐一处理,而非单一实例。其典型应用是:检查Bean属性的正确性或根据特定的标准更改Bean的属性。
  • 对Bean后置处理器而言,需要实现BeanPostProcessor接口

你可能感兴趣的:(#,JAVA-SSH,spring,ioc,应用)