天天看點

spring建立對象的三種方式詳解

前言

我們知道spring架構的核心就是IOC容器了,那麼IOC容器主要的作用就是建立對象和處理對象之間的依賴關系。本文主要講解IOC容器建立對象的三種方式。

建立對象的三種方式

1) 調用無參數構造器

2) 帶參數構造器

3) 工廠建立對象

包括:3.1 工廠類,靜态方法建立對象

3.2 工廠類,非靜态方法建立對象

1.調用無參數的構造器

具體如下:

User.java

public class User {

    private int id;
    private String name;



    public User() {
        super();
        System.out.println("------User對象建立【無參數構造器】------");
    }


    public User(int id, String name) {
        System.out.println("-----User對象建立【帶參數構造器】--------");
        this.id = id;
        this.name = 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;
    }


    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }
}           

Bean.xml配置如下:

<!-- 1. 預設無參數構造器 -->
    <bean id="user1" class="com.nwpu.geeker.User"></bean>           

測試:

// 測試:對象建立
    @Test
    public void testIOC() throws Exception {
        // 建立IOC容器對象
        ApplicationContext ac = new ClassPathXmlApplicationContext("com/nwpu/geeker/bean.xml");
        // 擷取容器中的對象
        User user = (User) ac.getBean("user");

        System.out.println(user);
    }           

2.帶參數構造器建立對象

例如:上面的user.java 有帶參的構造器,參數清單為(int,string).一般依賴注入對象的時候用的比較多。

配置如下:

<!-- 2. 帶參數構造器 -->
    <bean id="user2" class="com.nwpu.geeker..User">
        <constructor-arg index="0" type="int" value="100"></constructor-arg>
        <constructor-arg index="1" type="java.lang.String" value="Jack"></constructor-arg>
    </bean>           

其中index屬性表示參數的位置。Type表示類型,value表示指派,還有一個ref屬性下面将會介紹,表示可以引用IOC容器建立好的(已存在的)對象。

配置如下:

<!-- 定義一個字元串,值是"Jack" ;  String s = new String("jack")-->
    <bean id="str" class="java.lang.String">
        <constructor-arg value="Jacks"></constructor-arg>
    </bean>
    <bean id="user3" class="com.nwpu.geeker.User">
        <constructor-arg index="0" type="int" value="100"></constructor-arg>
        <constructor-arg index="1" type="java.lang.String" ref="str"></constructor-arg>
    </bean>           

ref屬性引用的就是IOC容器建立對象的id屬性值。

3.通過工廠類建立對象

3.1 通過執行個體化工廠,非靜态方法建立對象

先建立工廠javaBean

// 工廠,建立對象
public class ObjectFactory {

    // 執行個體方法建立對象
    public User getInstance() {
        return new User(100,"工廠:調用執行個體方法");
    }

    // 靜态方法建立對象
    public static User getStaticInstance() {
        return new User(101,"工廠:調用靜态方法");
    }
}           

配置檔案:

<!-- # 3.1 工廠類,執行個體方法 -->
    <!-- 先建立工廠 -->
    <bean id="factory" class="com.nwpu.geeker.ObjectFactory"></bean>
    <!-- 在建立user對象,用factory方的執行個體方法 -->
    <bean id="user4" factory-bean="factory" factory-method="getInstance"></bean>           

其中: factory-bean=”factory”指定工廠。factory-method=”getInstance”指定工廠的哪個方法。

3.2 工廠類: 靜态方法建立對象

<bean id="user" class="com.nwpu.geeker.ObjectFactory" factory-method="getStaticInstance"></bean>           

class 指定的就是工廠類型,這裡是和上面配置不同的地方。

factory-method 一定是工廠裡面的“靜态方法”

建立對象的細節問題

1) 對象建立: 單例/多例

在bean.xml配置檔案中,配置scope=”singleton”,為單例建立對象,如果不配置,預設也是單例方式。主要應用于service/dao層還有一些utils工具類等隻需要在伺服器啟動時初始化一次即可。

scope=”prototype”,表示多例方式建立對象,也就是當使用者需要使用這個對象時即建立對象,在ssh項目整合中主要應用于Action對象。這種方式一般在伺服器啟動時不會建立對象,在每次使用才建立。

2) 什麼時候建立?上面其實已經說了

scope=”prototype” 在用到對象的時候,才建立對象。(在ioc容器初始化之後)

scope=”singleton” 在伺服器啟動時候(容器初始化之前), 就已經建立了bean,且整個應用隻有一個。

3)是否延遲建立

lazy-init=”false” 預設為false, 不延遲建立,即在啟動時候就建立對象

lazy-init=”true” 延遲初始化, 在用到對象的時候才建立對象

(隻對單例有效)因為多例本來就是通路對象時才建立。

4) 建立對象之後,初始化/銷毀

init-method=”init_user” 【對應對象的init_user方法,在對象建立好之後執行 】

destroy-method=”destroy_user” 【在調用容器對象的destroy方法時候執行,(容器用實作類)】

public class User {

    private int id;
    private String name;



    public User() {
        super();
        System.out.println("------User對象建立------");
    }
    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;
    }

    public void init_user() {
        System.out.println("建立對象之後,初始化");
    }
    public void destroy_user() {
        System.out.println("IOC容器銷毀,user對象回收!");
    }

}           

測試:

@Test
    public void testIOC() throws Exception {
        // 得到IOC容器對象  【用實作類,因為要調用銷毀的方法】
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("com/nwpu/geeker/applicationContext.xml");
        System.out.println("-----容器建立-----");

        // 從容器中擷取bean
        User user1 = (User) ac.getBean("user");
        User user2 = (User) ac.getBean("user");

        System.out.println(user1);
        System.out.println(user2);

        // 銷毀容器對象 
        ac.destroy();
    }

    @Test
    public void test() throws Exception {
        // 容器對象
        ApplicationContext ac = new ClassPathXmlApplicationContext("com/nwpu/geeker/applicationContext.xml");
        System.out.println("-----容器建立完成-----");
        User user1 = (User) ac.getBean("user1");
    }           

繼續閱讀