1. 程式人生 > 其它 >spring -3 建立複雜物件及控制物件的建立次數

spring -3 建立複雜物件及控制物件的建立次數

技術標籤:筆記javaspring

目錄

什麼是複雜物件?

spring工廠建立複雜物件的3種方式:

1,實現spring提供的FactoryBean介面。

2,例項工廠:

3,靜態工廠

spring控制物件的建立次數:

spring為什麼要控制物件的建立次數呢?

如何控制:

什麼樣的物件只建立一次呢?


什麼是複雜物件?

簡單物件:直接通過new的方式可以直接建立的。Person per = new Person();

複雜物件:不能直接通過new構造方法來建立的。

例如:Connection物件,SqlSessionFactory物件。

spring工廠建立複雜物件的3種方式:

1,實現spring提供的FactoryBean介面。

public class ConnectionFactory implements FactoryBean<Connection> {

    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    //獲得物件的程式碼
    @Override
    public Connection getObject()  {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?serverTimezone=UTC","root","1234");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
//獲得物件的class型別
    @Override
    public Class<?> getObjectType() {
        return Connection.class;
    }
//預設是true,表示獲取的是單例
//    是否是單例物件
    @Override
    public boolean isSingleton() {
        return false;
    }
}

XML檔案中:

<bean id="conn" class="begin.ConnectionFactory"></bean>

test程式碼:

/**
     * 測試:建立複雜物件
     */
    @org.junit.Test
    public void test4(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
        Connection conn = (Connection) ctx.getBean("conn");
        System.out.println(conn);
    }

結果:

細節:Connection物件是不可公用的,而SqlSessionFactory是可以公用的。

配置檔案中:如果使用和普通物件一樣的配置方法,返回的就是複雜物件。若想要原來的物件,就要getBean("&conn").就會返回原來的那個類的物件。而不是由那個類建立的物件。

spring如何實現的?(明明我寫的是得到class類的方法,給我的確是這個類建立的物件)。

原因: if(bean instanceof FactoryBean) return bean.getObject();

總結:spring建立複雜物件的一種方式,spring原生提供,spring衍生框架中,大量應用了FactoryBean介面。

2,例項工廠:

避免了spring框架的侵入;整合遺留系統(有class檔案,而原始碼沒有或者不能輕易修改)。

顧名思義:將工廠例項化,建立物件。

例如:

public class ConectionFactory1 {
    public Connection getObject()  {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?serverTimezone=UTC","root","1234");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
}

XML檔案中:

<bean id="connFactory" class="begin.ConectionFactory1"></bean>
<!--    指定工廠物件,工廠得到物件方法-->
    <bean id="conn" factory-bean="connFactory" factory-method="getObject"></bean>

結果:

總結:返回物件類不需要指定class,需要指定factory-bean和factory-method。

3,靜態工廠

建立複雜物件是個靜態工廠類,建立方法是靜態方法。

public class ConectionFactory1 {

    public static Connection getObject() throws ClassNotFoundException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = null;
        try {
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?serverTimezone=UTC","root","1234");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
}

XML檔案中:

<bean id="conn" class="begin.ConectionFactory1" factory-method="getObject"></bean>

結果:

spring控制物件的建立次數:

spring為什麼要控制物件的建立次數呢?

比如所一個UserService只需要一個,一個UserDao也只需要一個(因為實現的功能是一樣的,過多的會產生更大記憶體開銷和冗餘)。

如何控制:

1,實現FactoryBean介面後,之中有一個isSingleton方法。就是制定建立的物件是否是單例(即自始至終得到的物件只有一個)。return true。即可。

2,在XML檔案bean標籤中有一個scope屬性,一個是prototype(原型表示建立多個一樣的),一個是singleton(單例)。

好處:節省不必要的記憶體開銷。

什麼樣的物件只建立一次呢?

各種dao和service。SqlSessionFactory和DispatchServlet(springMVC)的各種重量級資源(肯定都是執行緒安全的)。