本质上说,BeanFactory和ApplicationContext维护Bean定义及其相互依赖关系的高级工厂接口。通过他们我们可以访问Bean定义。

 

Spring的BeanFactory容器

这是一个简单的容器,它主要的功能是为依赖注入(DI)提供支持,这个容器接口在org.springframework.beans.factory.BeanFactory中被定义,在Spring中,有大量对BeanFactory接口的实现。其中,最常被使用的是XmlBeanFactory类。 这个容器从一个XML文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。

在资源宝贵的移动设备或者基于applet的应用当中,BeanFactory会被优先选择。否则,一般使用的是ApplicationContext,除非你有更好的理由选择BeanFactory。

 

Spring的ApplicationContext容器

Application Context是Spring中较高级的容器。和BeanFactory类似,它可以加载配置文件中定义的bean,将所有的bean集中在一起,当有请求的时候分配bean。

ApplicationContext包含BeanFactory所有的功能,一般情况下,相对于BeanFactory,ApplicationContext会被推荐使用。但BeanFactory仍然可以在轻量级应用中使用。

最常被使用的ApplicationContext接口实现:

· FileSystemXmlApplicationContext:该容器从XML文件中加载已被定义的bean。在这里,你需要提供给构造器XML文件的完整路径

· ClassPathXmlApplicationContext:该容器从XML文件中加载已被定义的bean。在这里,你不需要提供XML文件的完整路径,只需正确配置CLASSPATH环境变量即可,因为,容器会从CLASSPATH中搜索配置文件。

· WebXmlApplicationContext:该容器会在一个web应用程序的范围内加载在XML文件中已被定义的bean。

 

Spring容器配置web.xml文件

<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <!-- <param-value>classpath*:config/applicationContext.xml</param-value> -->  
        <param-value>/WEB-INF/classes/config/applicationContext.xml</param-value>  
    </context-param>  
    
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  
    <servlet>   
        <servlet-name>springmvc</servlet-name>   
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <!-- <param-value>classpath*:config/Springmvc-servlet.xml</param-value> -->  
            <param-value>/WEB-INF/classes/config/Springmvc-servlet.xml</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>   
    </servlet>    
    <servlet-mapping>   
        <servlet-name>springmvc</servlet-name>   
        <url-pattern>/</url-pattern>    
    </servlet-mapping>  
</web-app>  

 

其中:

<listener>  
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
</listener>  

ContextLoaderListener是Spring的监听器,它的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <!-- <param-value>classpath*:config/applicationContext.xml</param-value> -->  
    <param-value>/WEB-INF/classes/config/applicationContext.xml</param-value>  
</context-param>

这段配置是用于指定applicationContext.xml配置文件的位置,可通过context-param加以指定:
classpath是指 WEB-INF文件夹下的classes目录。

classpath 和 classpath* 区别:

classpath:只会到你的class路径中查找找文件; 
classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找. 

如果applicationContext.xml配置文件存放在src目录下,就好比上面的代码结构中的存放位置,那么在web.xml中的配置就如下所示:

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>classpath:applicationContext.xml</param-value>  
</context-param>  

如果applicationContext.xml配置文件存放在WEB-INF下面,那么在web.xml中的配置就如下所示:

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>WEB-INF/applicationContext*.xml</param-value>  
</context-param>

需要注意的是,部署到应用服务器后,src目录下的配置文件会和class文件一样,自动copy到应用的 classes目录下,spring的 配置文件在启动时,加载的是web-info目录下的applicationContext.xml, 运行时使用的是web-info/classes目录下的applicationContext.xml。因此,不管applicationContext.xml配置文件存放在src目录下,还是存放在WEB-INF下面,都可以用下面这种方式来配置路径:

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>WEB-INF/applicationContext*.xml</param-value>  
</context-param>  

当有多个配置文件加载时,可采用下面代码来配置:

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>   
        classpath*:conf/spring/applicationContext_core*.xml,   
        classpath*:conf/spring/applicationContext_dict*.xml,  
        classpath*:conf/spring/applicationContext_hibernate.xml,  
        ......  
    </param-value>  
</context-param>  

也可以用下面的这种方式:

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>classpath*:**/applicationContext-*.xml</param-value>  
</context-param> 

"**/"表示的是任意目录; 
"**/applicationContext-*.xml"表示任意目录下的以"applicationContext-"开头的XML文件。 

Spring配置文件最好以"applicationContext-"开头,且最好把所有Spring配置文件都放在一个统一的目录下,也可以分模块创建

 

Spring中Bean的配置

Bean定义

被称作bean的对象是构成应用程序的支柱也是由SpringIoC容器管理的。bean是一个被实例化,组装,并通过SpringIoC容器所管理的对象。这些bean是由用容器提供的配置元数据创建的。

SpringIoC容器完全由实际编写的配置元数据的格式解耦。有下面三个重要的方法把配置元数据提供给Spring容器:

· 基于XML的配置文件

· 基于注解的配置

· 基于Java的配置

 

Bean的作用域

singleton 该作用域将bean的定义限制在每一个Spring IoC容器中的一个单一实例(默认)。

prototype 该作用域将单一bean的定义限制在任意数量的对象实例。

request 该作用域将bean的定义限制为HTTP请求。只在web-aware、Spring ApplicationContext的上 下文中有效。

session 该作用域将bean的定义限制为HTTP会话。

global-session    该作用域将bean的定义限制为全局HTTP会话。

 

bean的生命周期

理解Spring Bean的生命周期很容易。当一个bean被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当bean不再需要,并且从容器中移除时,可能需要做一些清除工作。

为了定义安装和拆卸一个bean,我们只要声明带有init-method和destroy-method参数的。

① 初始化回调

在基于XML的配置元数据的情况下,可以使用init-method属性来指定初始化方法。

② 销毁回调

在基于XML的配置元数据的情况下,可以使用destroy-method属性来制定销毁方法。

需要注意的问题:

destroy-method 只对 scope="singleton" 有效 

销毁方法,必须关闭ApplicationContext对象(手动调用),才会被调用

ClassPathXmlApplicationContext applicationContext 
= new ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.close();

③在顶级的bean里面即元素中声明default-init-method属性,可以为容器中所有的bean指定同一个初始化或销毁回调方法。

④bean的延迟实例化

在ApplicationContext实现的默认行为就是在启动的时候将所有singleton提前进行实例化,如果不想在ApplicationContext初始化时被提前实例化,可以使用元素的"lazy-init=true"属性,一个延迟实例化的bean将在第一次被用到的时候初始化。

如果要为容器中所有的bean指定延迟实例化特性,可以在里面指定"default-lazy-init=true"属性。

 

指定bean的依赖关系

初始化beanOne会首先初始化manager1,manager2,当一个bean对多个bean存在依赖关系时,depend-on属性可以指定多个bean名,用逗号隔开。                                                

<bean id="beanOne" depend-on="manager1,manager2"></bean>
<bean id="manager1"></bean>
<bean id="manager2"></bean>

 

Spring配置bean实例化

① 使用类构造器实例化(默认无参数)

id或name属性:用于指定bean的名称,用于从Spring容器中查找这个bean对象。

class属性:用于指定bean类型,会自动调用构造器创建对象。

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserController uc = ctx.getBean("userController",UserController.class);

 

② 使用静态工厂方法实例化(简单工厂模式)

public class Person { //创建工厂类 
private Person(String s){
  System.out.println(s);
 }

 public void say() {
  System.out.println("00000000000000");  
 }
 public static Person getPerson(){ //创建静态方法
  return new Person("hello"); //返回实例化的类的对象
 }
}
public class Test {
 public static void main(String[] args) {
  ApplicationContext  ctx =new  ClassPathXmlApplicationContext("applicationContext.xml");

  Person person =  (Person) ctx.getBean("person");
  person.say();
 }
}
<bean id="speaker03" class="com.mahaochen.spring.learn03.Speaker" factory-method="getPerson"></bean> 

 

③ 使用实例工厂方法实例化

实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法。

public class People {  
   private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
<bean id="PeopleFactory" class="com.mahaochen.spring.PeopleFactory"></bean>  
    <!-- 使用实例工厂Bean创建Bean -->  
    <bean id="" class="com.mahaochen.spring.Speaker"  
        factory-bean="PeopleFactory" factory-method="createPeopleInstance" >  
  </bean> 

 

posted on 2018-05-02 14:32  FuYingju  阅读(60)  评论(0编辑  收藏  举报