天天看點

Spring 架構學習(三)---- IOC建立對象

文章目錄

  • ​​Spring 架構學習(三)---- IOC建立對象的方式​​
  • ​​1、IOC 什麼時候建立對象?​​
  • ​​BeanFactory(不推薦使用)​​
  • ​​ApplicationContext​​
  • ​​兩者差別​​
  • ​​優缺點,各有利弊​​
  • ​​2、IOC 如何建立對象?​​
  • ​​(1)根據參數下标進行指派(推薦)​​
  • ​​(2)根據參數類型進行指派(不推薦)​​
  • ​​(3)根據參數名進行指派(推薦)​​
  • ​​3、IOC容器存儲一個bean,取出多個對象是否相同?​​

Spring 架構學習(三)---- IOC建立對象的方式

  寫完了第一個Spring的程式,相信已經對spring已經有所了解了,那麼我們這節來了解一下,IOC是如何建立對象,什麼時候建立對象的。

1、IOC 什麼時候建立對象?

  Spring 提供了兩種 IoC 容器,分别為 BeanFactory 和 ApplicationContext

我們先對兩種進行介紹一下

BeanFactory(不推薦使用)

  BeanFactory 是基礎類型的 IoC 容器,簡單來說,BeanFactory 就是一個管理 Bean的工廠,它主要負責初始化各種 Bean,并調用它們的生命周期方法。

  BeanFactory 接口有多個實作類,最常見的是 XmlBeanFactory類,它是根據 XML 配置檔案中的定義裝配 Bean 的。

  建立 BeanFactory 執行個體時,需要提供 Spring 所管理容器的詳細配置資訊,這些資訊通常采用 XML 檔案形式管理。其加載配置資訊的代碼具體如下所示

BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("D://applicationContext.xml"));      

ApplicationContext

  ApplicationContext 是 BeanFactory 的子接口,也被稱為應用上下文,它不僅提供了 BeanFactory 的所有功能,還添加了對 i18n(國際化)、資源通路、事件傳播等方面的良好支援。

  ApplicationContext 接口有兩個常用的實作類,具體如下。

1)ClassPathXmlApplicationContext(重點認識)

  該類從類路徑 ClassPath 中尋找指定的 XML 配置檔案,找到并裝載完成 ApplicationContext 的執行個體化工作,具體如下所示。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);      

2)FileSystemXmlApplicationContext(知道就行)

  該類從指定的檔案系統路徑中尋找指定的 XML 配置檔案,找到并裝載完成 ApplicationContext 的執行個體化工作,具體如下所示。

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);      

  在使用 Spring 架構時,可以通過執行個體化其中任何一個類建立 Spring 的 ApplicationContext 容器。

兩者差別

BeanFactory

  BeanFactory在啟動的時候不會去執行個體化Bean,中有從容器中拿Bean的時候才會去執行個體化;

ApplicationContext

  ApplicationContext在啟動的時候就把所有的Bean全部執行個體化了。

  是以我們可以得知,對象在什麼時候建立,我們使用的是ApplicationContext,是以在Spring啟動的時候就已經把所有的Bean對象給建立好了。

優缺點,各有利弊

  • 延遲執行個體化的優點:(BeanFactory)

先快後慢

  應用啟動的時候占用資源很少;對資源要求較高的應用,比較有優勢;

  • 不延遲執行個體化的優點: (ApplicationContext)

先慢後快

1.  所有的Bean在啟動的時候都加載,在後續的操作中系統運作的速度快;

2.  在啟動的時候所有的Bean都加載了,我們就能在系統啟動的時候,盡早的發現系統中的配置問題

2、IOC 如何建立對象?

(1)我們給實體類中加了一個無參構造方法、還有帶一個參數的構造方法。

package com.kuang.pojo;

public class Hello {
    private String str;

    public Hello() {
        System.out.println("這是一個無參構造!");
    }

    public Hello(String str) {
        this.str = str;
        System.out.println("這是一個帶有一個參數的構造器!");
    }

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}      

(2)配置xml中的bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="hello" class="com.kuang.pojo.Hello">
        <property name="str" value="Hello Spring!"/>
    </bean>
</beans>      

(3)編寫業務層代碼

package com.kuang.service;

import com.kuang.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class HelloService {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        Hello hello = context.getBean("hello", Hello.class);
        System.out.println(hello);
    }
}      

運作之後,預設調用的是無參的構造方法

Spring 架構學習(三)---- IOC建立對象

我們可以得到一個結論:

如果不做專門的配置,那麼bean是通過無參構造來進行建立對象的

如果想要對實體類進行有參構造的建立怎麼實作呢?

IOC建立有參構造器對象的三種方式

這三種方式同樣,推薦大家一定要上spring的官方進行檢視,說的非常清楚了。

(1)根據參數下标進行指派(推薦)

Spring 架構學習(三)---- IOC建立對象
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>      
  • index 代表構造參數的下标,從0開始
  • value 代表設定的值

在文檔中說明,通過index(從0開始),對對應位置的構造參數進行設定value,即可通過有參構造器建構對象

(1)寫一個User類,中有四個構造函數,有參,一個構造參數…,

package com.kuang.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

@Getter
@Setter
@ToString
public class User {
    private int id;
    private String userName;
    private String password;

    public User() {
        System.out.println("無參構造進行建立對象!");
    }

    public User(int id) {
        this.id = id;
        System.out.println("一個參數構造的進行建立對象");
    }

    public User(int id, String userName) {
        this.id = id;
        this.userName = userName;
        System.out.println("兩個參數構造進行建立對象");
    }

    public User(int id, String userName, String password) {
        this.id = id;
        this.userName = userName;
        this.password = password;
        System.out.println("三個參數構造進行建立對象");
    }


}      

(2)xml檔案通過下标的方式配置bean,隻設定了一個參數

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

 <bean id="user" class="com.kuang.pojo.User">
     <constructor-arg index="0" value="1"/>
 </bean>

</beans>      

(3)然後通過ApplicationContext啟動Spring容器

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        User user = context.getBean("user",User.class);
    }      

(4)運作結果

Spring 架構學習(三)---- IOC建立對象

(2)根據參數類型進行指派(不推薦)

Spring 架構學習(三)---- IOC建立對象
<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>      
  • type 構造參數的類型,如果是普通類型直接寫int、double,如果是引用類型寫全限定名
  • value 設定的參數值

在文檔中說明,通過type(引用類型要寫全限定名),對對應類型的構造參數進行設定value,即可通過有參構造器建構對象

有一個問題,如果多個構造參數都是同一個類型呢?

答:會根據标簽的順序對同一類型的參數進行從前到後指派。

(1)前面的User類不變

(2)通過類型配置bean建立對象

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

 <bean id="user" class="com.kuang.pojo.User">
     <constructor-arg type="int" value="1"/>
     <constructor-arg type="java.lang.String" value="userName"/>
     <constructor-arg type="java.lang.String" value="password"/>
 </bean>

</beans>      

(3)啟動Spring,如上

(4)檢視運作結果

Spring 架構學習(三)---- IOC建立對象

(3)根據參數名進行指派(推薦)

Spring 架構學習(三)---- IOC建立對象
<beans>
    <bean id="thingOne" class="x.y.ThingOne">
        <constructor-arg ref="thingTwo"/>
        <constructor-arg ref="thingThree"/>
    </bean>

    <bean id="thingTwo" class="x.y.ThingTwo"/>

    <bean id="thingThree" class="x.y.ThingThree"/>
</beans>      
  • name 構造參數的類型,如果是普通類型直接寫int、double,如果是引用類型寫全限定名
  • value/ref 設定的參數值

這種方式看着非常直覺,非常容易了解,這種方式與設定類中的屬性是一樣的

其他都不變,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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

 <bean id="user" class="com.kuang.pojo.User">
    <constructor-arg name="id" value="1"/>
     <constructor-arg name="userName" value="root"/>
     <constructor-arg name="password" value="123456"/>
 </bean>

</beans>      

檢視運作結果

Spring 架構學習(三)---- IOC建立對象

3、IOC容器存儲一個bean,取出多個對象是否相同?

(1)編寫實體類User

package com.kuang.pojo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class User {
    private int id;
    private String userName;
    private String password;

}      

(2)在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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

 <bean id="user" class="com.kuang.pojo.User"/>

</beans>      

(3)根據同一個bean取出多個對象

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        User user = context.getBean("user",User.class);
        User user2 = context.getBean("user",User.class);
        System.out.println(user==user2);

    }      

(4)運作結果

Spring 架構學習(三)---- IOC建立對象