天天看點

SpringIOC控制反轉之XML配置

IOC概念

​ ( Inversion of Control,縮寫為 IoC),是面向對象程式設計中的一種設計原則,可以用來降低計算機代碼之間的耦合度。

​ 簡單來說Spring中的IOC控制反轉就是将對象執行個體化對象的控制權,由手動的new,轉為交給Spring架構通過反射機制,進行對象的執行個體化。

​ 在Spring入門中我們已經使用了xml配置來控制對象的建立,實作了控制反轉。

容器的使用

​ 前面說了控制反轉就是将創見對象的控制權由new,轉為交給Spring架構通過反射機制,進行對象的執行個體化,Spring容器進行執行個體化後會将建立的執行個體對象放入Spring容器,那麼Spring容器到底是什麼東西?

概念了解

​ 容器,容器,顧名思義就是用來裝東西的;如我們生活中的水杯,水桶、水盆等等,是以我們的Spring容器也是用來裝東西的;水杯、水桶用來裝水,而我們的Spring容器就是用來裝對象執行個體的。

IOC 容器的體系結構

  • spring容器

    Spring的容器有兩個

    1. BeanFactory
    2. ApplicationContext
  • 兩者的關系
    SpringIOC控制反轉之XML配置

    可以看出,他們兩個都是接口,并且ApplicationContext是BeanFactory的子接口。

    在BeanFactory中提供了配置架構和基本功能

    在ApplicationContext中增加了更多針對企業的功能。

  • 兩者的差別

    建立對象的時間點不一樣。

    ApplicationContext

    :隻要一讀取配置檔案,預設情況下就會建立對象,類似與單例模式中的餓漢式。

    BeanFactory

    :什麼時候使用,什麼時候建立對象,類似與單例模式中的懶漢式。

IoC 容器執行個體化的方式

​ 上面已經知道 Spring 的容器是通過一個接口

org.springframework.context.ApplicationContext

表示,并負責執行個體化,配置群組裝 Bean 對象。容器通過讀取 xml 檔案中的配置資訊來擷取關于執行個體化對象,配置屬性等指令。

​ 而

ApplicationContext

隻是一個接口,我們通常建立

ClassPathXmlApplicationContext

的執行個體或者

FileSystemXmlApplicationContext

的執行個體。

​ 前者是從類路徑中擷取上下文定義檔案,後者是從檔案系統或 URL 中擷取上下文定義檔案。

  • 從類路徑下讀取Spring配置檔案,建立Spring容器
    public void userSaveTest() {
            //建立spring容器,參數指定spring配置檔案的全名
            ClassPathXmlApplicationContext context = new
                    ClassPathXmlApplicationContext("applicationContext.xml");
         
         //可以使用多态方式也可以
         /*
         	 ApplicationContext context = new
                    ClassPathXmlApplicationContext("applicationContext.xml");
         */
    }
               
  • 從電腦本地讀取配置檔案,建立Spring容器
    public void userSaveTest() {
            //建立spring容器,參數指定spring配置檔案的全名
            FileSystemXmlApplicationContext context = new
                    FileSystemXmlApplicationContext("D:\\applicationContext.xml");
    }
               

bean 标簽中的屬性介紹

我們知道Bean标簽的作用就是在架構啟動加載配置檔案的時候,根據配置的類的全限定名,建立執行個體對象,放入Spring容器進行統一管理,

Bean标簽回顧

以上我們隻用到了id屬性和class屬性,那麼來看一下是否還有其他屬性。

常用屬性介紹

屬性 描述
id 定義配置的Bean标簽的唯一辨別
name 同id屬性
class 表示要描述的類,也就是當加載spring配置檔案的時候,要根據此屬性指定的類的全限定名建立的執行個體對象。
factory-bean 主要用于工廠模式執行個體化 bean 的時候使用,這個屬性用于引用配置的工廠Bean
factory-method

主要用于工廠模式執行個體化 bean 的時候使用,這個屬性表示引用工廠Bean中的指定方法。

在普通工廠模式下factory-bean與factory-method結合使用,靜态工廠時單獨使用factory-method

init-method Bean初始化的時候,指定執行的方法。
destroy-method Bean銷毀的時候,指定執行的方法。
scope 指定配置的Bean的作用範圍,一般用多例還是單例來表述它。
lazy-init 懶加載
autowire 依賴注入
depends-on 依賴于某個執行個體

id和name屬性

用于定義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" name="user2" class="com.wyan.entity.User" ></bean>

</beans>


           

測試類代碼

public static void main(String[] args) {
    ApplicationContext context =
        new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    System.out.println(context.getBean("user"));
    System.out.println(context.getBean("user2"));
}
           

無論是使用id還是使用name,都能從Spring容器中擷取Bean

class 屬性

Spring的底層是通過反射來建立的執行個體對象,但是他不知道建立哪個類的執行個體對象啊;是以通過Class屬性指定要建立的執行個體對象的全限定類名。

factorybean 和 factorymethod 屬性

這兩個屬性主要用于工廠模式執行個體化 bean 的時候使用

  1. 使用靜态工廠模式擷取Bean

    靜态工廠類代碼

    //方法和參數都是靜态的
    public class User {
        
        private static User user = new User();
        
        private User() {}
    
        public static User createInstance() {
            return user;
        }
    }
               
    applicationContext配置
    <!--
    	通過factory-method屬性,引用User工廠類中的createInstance方法,該方法傳回值是一個user對象;
    	是以當我們使用Bean标簽的id擷取Bean的時候,得到的是createInstance方法的傳回值  ->  user對象
    -->
    <bean id="user" class="com.wyan.entity.User" factory-method="createUserInstance"/>
               
  2. 使用普通工廠擷取Bean

    普通工廠類代碼

    public class BeanFactory {
    
        private static User1 user1 = new User1();
    
        private static User2 user2 = new User2();
    
        public User1 createUser1() {
            return user1;
        }
    
        public User2 createUser2() {
            return user2;
        }
    }
               
    applicationContext配置
    <!--spring執行個體化工廠對象 用于建立java執行個體 -->
    <bean id="beanFactory" class="com.wyan.factory.BeanFactory"></bean>
    
    <!-- 被工廠建立的對象執行個體 -->
    <bean id="user1" factory-bean="beanFactory" factory-method="createUser1"/>
               
    先要配置工廠Bean,然後引用工廠Bean的id,使用factory-method屬性,引用工廠Bean中的方法,得到該方法的傳回值,也就得到了User1執行個體對象

init-method 和 destroy-method 屬性的使用

init-method 就是 bean 被初始化後執行的方法,destory-method 就是 bean 被銷毀執行的代碼。

  • 測試代碼User類
    public class User {
    
        public User(){
            System.out.println("我被spring執行個體化了");
        }
    
        public void initMethod(){
            System.out.println("user類執行個體化時候執行的代碼");
        }
        public void destoryMethod(){
            System.out.println("user類執行個體被銷毀時候執行的代碼");
        }
    }
               
  • applicationContext.xml配置
  • 測試代碼
    public static void main(String[] args) {
        ApplicationContext context =
            new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    
    }
               
  • 結果
SpringIOC控制反轉之XML配置

scope 屬性

常用屬性值

​ 預設為singleton 單例

  1. singleton:單例建立對象,當建立Spring容器的時候,對象就會建立,銷毀Spring容器的時候,對象也就銷毀;每次從Spring容器中擷取的對象都是同一個。
  2. prototype:多例建立對象,當擷取對象的時候,才會建立對象,銷毀Spring容器的時候,對象不會銷毀,由其它機制管理銷毀;每次從Spring中擷取的對象都不是同一個。
    <!--單例-->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton"/>
    <!--多例-->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="prototype"/>