1、创建对象:单例/多例 模式;

实体类 User.java:

package com.spring.demo;

/**
 * 实体类 javabean
 */
public class User {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

}

主配置文件 bean.xml:spring 的主配置文件名为 applicationContext.xml 和 bean.xml 都可以;

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置 IOC 容器:要创建的所有的对象都配置在这里 -->
    <bean id="user" class="com.spring.demo.User"/>

</beans>

测试程序 Demo2.java:

package com.spring.demo;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo2 {

    // 创建 IOC 容器对象
    private ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");

    /**
     * 对象创建:单例/多例
     */
    @Test
    public void test1() {
        // 从 IOC 容器中获取 bean
        User user1 = (User) context.getBean("user");
        User user2 = (User) context.getBean("user");

        // 测试两次获取的对象是不是同一个对象
        System.out.println(user1);
        System.out.println(user2);
    }
}

执行 test1 结果:

对已经创建的容器挂载镜像 创建容器对象的类是_User

可以发现,默认情况下,两次获取的是同一个对象,即默认是 单例模式;

可以在 bean.xml 配置文件中通过 scope 属性进行设置,如下所示:

对已经创建的容器挂载镜像 创建容器对象的类是_spring_02

scope="singleton" 表示单例模式,如果不设置 scope 属性,默认就是单例模式;

如果设置 scope="prototype" 表示多例模式,如下:

对已经创建的容器挂载镜像 创建容器对象的类是_对已经创建的容器挂载镜像_03

多例模式下再次执行 test1,结果如下:

对已经创建的容器挂载镜像 创建容器对象的类是_对已经创建的容器挂载镜像_04

可以看到,多例模式下,两次获取的对象不一样;

总结:

scope="singleton":表示单例模式(默认),即只创建一个对象,每次获取的都是同一个对象;适合 service / dao 对象的创建;

scope="prototype":表示多例模式,即每次获取对象的时候都会创建新的对象;适合 action 对象的创建:每次访问 action,都要创建一个新的 action 对象;

 

2、对象的创建时机:

在实体类 User.java 中添加一个无参构造,记录 bean 对象创建的时机:

对已经创建的容器挂载镜像 创建容器对象的类是_spring_05

修改测试程序 test1 如下:记录 IOC 对象创建的时机

对已经创建的容器挂载镜像 创建容器对象的类是_User_06

当 scope="singleton" 时,执行 test1,结果如下:

可以发现:在启动程序的时候,先创建 User 对象,后创建 IOC 容器对象;因为单例模式下,整个应用程序只有这一个 User 对象,所以在程序一启动的时候就先创建;

对已经创建的容器挂载镜像 创建容器对象的类是_User_07

当 scope="prototype" 时,执行 test1,结果如下:

可以发现:先创建的 IOC 容器对象,在用到 bean 对象的时候才去创建 bean 对象;因为多例模式下,每次创建的对象都不一样,所以只有在使用的时候才会去创建;

对已经创建的容器挂载镜像 创建容器对象的类是_spring_08

 

3、是否延迟创建:通过 lazy-init 属性设置是否延迟创建;只对 单例模式 有效;

lazy-init="false",表示不延迟创建,即在程序启动的时候就创建 bean 对象;(默认情况)

对已经创建的容器挂载镜像 创建容器对象的类是_User_09

不延迟创建的结果如下:程序启动的时候直接创建 bean 对象;

对已经创建的容器挂载镜像 创建容器对象的类是_对已经创建的容器挂载镜像_10

如果设置 lazy-init="true",表示延迟创建:

对已经创建的容器挂载镜像 创建容器对象的类是_对已经创建的容器挂载镜像_11

延迟创建的结果如下:可以看到先创建的 IOC 容器对象,在用到 bean 对象的时候,才创建 bean 对象;

对已经创建的容器挂载镜像 创建容器对象的类是_对已经创建的容器挂载镜像_12

 

4、对象创建之后的 初始化和销毁:

在实体类 User.java 中添加一个 初始化方法(init_user),和一个销毁方法(destroy_user):

对已经创建的容器挂载镜像 创建容器对象的类是_spring_13

在 bean.xml 中配置 初始化和销毁方法:

对已经创建的容器挂载镜像 创建容器对象的类是_xml_14

执行下面代码:

对已经创建的容器挂载镜像 创建容器对象的类是_xml_15

结果为:

对已经创建的容器挂载镜像 创建容器对象的类是_对已经创建的容器挂载镜像_16

总结:

init-method="init_user" :对应对象的 init_user 方法,在对象创建之后执行 ;
destroy-method="destroy_user" :对应对象的 destroy_user 方法,在调用容器对象的 destroy 方法时候执行;

注意:创建容器要用实现类 ClassPathXmlApplicationContext;