Spring學習2:IOC(控制反轉)和容器

Spring IOC容器

IOC(控制反轉)容器:

  • Spring容器是Spring框架中的一個核心組件,容器將創建對象,把它們聯繫在一起並配置它們,管理它們的整個生命週期從創建到銷燬。IOC容器是具有依賴注入功能的容器,它可以創建對象,並負責對對象進行實例化、定位、配置應用程序中的對象及建立這些對象間的依賴。平時我們new一個新的實例,控制權在我們程序員的手裏,而“控制翻轉”就是指的是new的實例工作不再由程序員來做,而是交給Spring容器來做,這一節學習我們就來學習Spring的容器~

spring容器

一、Spring BeanFactory容器

1、描述

  • Spring BeanFactory 容器,它是最簡單的容器,給 DI 提供了基本的支持,它用 org.springframework.beans.factory.BeanFactory 接口來定義。BeanFactory 或者相關的接口,如 BeanFactoryAware ,InitializingBean,DisposableBean,在 Spring 中仍然存在具有大量的與 Spring 整合的第三方框架的反向兼容性的目的。
  • 在Spring中,有大量對BeanFactory接口的實現,最常使用的是XmlBeanFactory類。該容器從XML文件中讀取配置元數據,由這些元數據來生成一個被配置化的系統或者應用程序。

2、Spring BeanFactory的使用

  • 第一步:創建一個名爲 SpringExample 的工程並在 src 文件夾下新建一個名爲 studio_day1 的包,在與src文件同層次的文件路徑中新建一個lib文件夾。
  • 第二步:把Spring的所有相關jar包導入到lib文件夾中,然後右鍵,選擇 Add External JARs 選項,導入 Spring 的庫文件。
  • 第三步:在studio_day1下新建名爲HelloWorld的class和名爲Main的class。
  • 第四步:在src文件下創建Bean的配置文件Spring-conf.xml
  • 第五步:開始配置Bean文件。

HelloWorld.java文件內容:

package studio_day_1;

public class HelloWorld {

    private String name;

    public String getName() {
        return name;
    }

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

    public void sayhello(){
        System.out.println("hello !"+ name);
    }
}

Main.java文件的內容:

package studio_day_1;


import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;

public class Main {
    public static void main(String[] args) {
        //創建一個spring ioc容器
        XmlBeanFactory context=new XmlBeanFactory(new ClassPathResource("spring-conf.xml"));
        //FileSystemXmlApplicationContext 必須使用絕對地址 否則會找不到xml文件
        HelloWorld helloWorld=(HelloWorld) context.getBean("helloworld");
        helloWorld.sayhello();
    }
}

Main函數中,我們使用的時候需要注意:

  • 第一步利用框架提供的 XmlBeanFactory() API 去生成工廠 bean 以及利用 ClassPathResource() API 去加載在路徑 CLASSPATH 下可用的 bean 配置文件。XmlBeanFactory() API 負責創建並初始化所有的對象,即在配置文件中提到的 bean
  • 第二步利用第一步生成的 bean 工廠對象的 getBean() 方法得到所需要的 bean。 這個方法通過配置文件中的 bean ID 來返回一個真正的對象,該對象最後可以用於實際的對象。一旦得到這個對象,你就可以利用這個對象來調用任何方法,相當於new了一個新對象,可以調用該類的所有公共函數和共有屬性。

spring-conf.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="helloworld" class="studio_day_1.HelloWorld">
        <property name="name" value="Spring!"/>
    </bean>
</beans>

注意:在xml配置文件中,bean id不能重複,class必須是類的包名+類名。
如果所有配置都成功,運行結果如下:
在這裏插入圖片描述

二、Spring ApplicationContext容器

Spring ApplicationContext 容器

  • Application Context 是 BeanFactory 的子接口,也被成爲 Spring 上下文。
  • Application Context 是 spring 中較高級的容器。和 BeanFactory 類似,它可以加載配置文件中定義的 bean,將所有的 bean 集中在一起,當有請求的時候分配 bean。 另外,它增加了企業所需要的功能,比如,從屬性文件中解析文本信息和將事件傳遞給所指定的監聽器。這個容器在 org.springframework.context.ApplicationContext interface 接口中定義。
  • ApplicationContext 包含 BeanFactory 所有的功能,一般情況下,相對於 BeanFactory,ApplicationContext 會更加優秀。當然,BeanFactory 仍可以在輕量級應用中使用,比如移動設備或者基於 applet 的應用程序。
  • 最常使用的ApplicationContext接口實現:
    • FileSystemXmlApplicationContext:該容器從 XML 文件中加載已被定義的 bean。在這裏,你需要提供給構造器 XML 文件的完整路徑。
    • ClassPathXmlApplicationContext:該容器從 XML 文件中加載已被定義的 bean。在這裏,你不需要提供 XML 文件的完整路徑,只需正確配置 CLASSPATH 環境變量即可,因爲,容器會從 CLASSPATH 中搜索 bean 配置文件。
    • WebXmlApplicationContext:該容器會在一個 web 應用程序的範圍內加載在 XML 文件中已被定義的 bean。

接下來我們測試Spring ApplicationContext容器:
構建過程和Spring BeanFactory容器類似,這裏就不贅述。
HelloWorld.java文件內容:

package studio_day_1;

public class HelloWorld {

    private String name;

    public String getName() {
        return name;
    }

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

    public void sayhello(){
        System.out.println("hello !"+ name);
    }
}

Main.java文件內容:

package studio_day_1;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        //創建一個spring ioc容器
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-conf.xml");
        ApplicationContext context1=
                new FileSystemXmlApplicationContext("C:\\Users\\ouguangji\\Desktop\\Envs\\spring_stdio_1\\src\\spring-conf.xml");
        //FileSystemXmlApplicationContext 必須使用絕對地址 否則會找不到xml文件
        HelloWorld helloWorld=(HelloWorld) context.getBean("helloworld");
        HelloWorld helloWorld1=(HelloWorld) context1.getBean("helloworld");
        helloWorld.sayhello();
        helloWorld1.sayhello();
    }
}

由上可以得到使用ClassPathXmlApplicationContext,可以直接使用xml文件,不需要絕對路徑就可以進行使用,但是在使用FileSystemXmlApplicationContext的時候,必須把xml文件寫入絕對路徑纔可以正常運行。

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="helloworld" class="studio_day_1.HelloWorld">
        <property name="name" value="Spring!"/>
    </bean>
</beans>

三、Spring Bean後置處理器

Spring——Bean 後置處理器 描述:

  • Bean 後置處理器允許在調用初始化方法前後對 Bean 進行額外的處理。

  • BeanPostProcessor 接口定義回調方法,你可以實現該方法來提供自己的實例化邏輯,依賴解析邏輯等。你也可以在 Spring 容器通過插入一個或多個 BeanPostProcessor 的實現來完成實例化,配置和初始化一個bean之後實現一些自定義邏輯回調方法。

  • 你可以配置多個 BeanPostProcessor 接口,通過設置 BeanPostProcessor 實現的 Ordered 接口提供的 order 屬性來控制這些 BeanPostProcessor 接口的執行順序。

  • BeanPostProcessor 可以對 bean(或對象)實例進行操作,這意味着 Spring IoC 容器實例化一個 bean 實例,然後 BeanPostProcessor 接口進行它們的工作。

  • ApplicationContext 會自動檢測由 BeanPostProcessor 接口的實現定義的 bean,註冊這些 bean 爲後置處理器,然後通過在容器中創建 bean,在適當的時候調用它。

實現步驟如下:

步驟 描述
1 創建一個名稱爲 SpringExample 的項目,並且在創建項目的 src 文件夾中創建一個包 com.tutorialspoint。
2 使用 Add External JARs 選項,添加所需的 Spring 庫。
3 在 包中創建 Java 類 HelloWorld、InitHelloWorld 和 MainApp。
4 在 src 文件夾中創建 Beans 配置文件 spring-conf.xml。
5 最後一步是創建的所有 Java 文件和 Bean 配置文件的內容,並運行應用程序,解釋如下所示。

這裏是 HelloWorld.java 文件的內容:

package studio_day_1;

public class HelloWorld {
    private String message;
    public void setMessage(String message){
        this.message  = message;
    }
    public void getMessage(){
        System.out.println("Your Message : " + message);
    }
    public void init(){
        System.out.println("Bean is going through init.");
    }
    public void destroy(){
        System.out.println("Bean will destroy now.");
    }
}

這是InitHelloWorld.java文件內容:

  • 這是實現 BeanPostProcessor 的非常簡單的例子,它在任何 bean 的初始化的之前和之後輸入該 bean 的名稱。你可以在初始化 bean 的之前和之後實現更復雜的邏輯,因爲你有兩個訪問內置 bean 對象的後置處理程序的方法。
package studio_day_1;

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.BeansException;
public class InitHelloWorld implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeforeInitialization : " + beanName);
        return bean;  // you can return any other object as well
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("AfterInitialization : " + beanName);
        return bean;  // you can return any other object as well
    }
}

這是Main.java文件內容:

package studio_day_1;


import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class Main {
    public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring-conf.xml");
        HelloWorld obj = (HelloWorld) context.getBean("helloworld");
        obj.getMessage();
        context.registerShutdownHook();
    }
}

這是spring-conf.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="helloworld" class="studio_day_1.HelloWorld"
    init-method="init" destroy-method="destroy">
        <property name="message" value="Hello World!"/>
    </bean>

    <bean class="studio_day_1.InitHelloWorld"/>
</beans>

配置完畢運行結果如下:
在這裏插入圖片描述
根據這個Spring Bean後置器的機制,我們就可以很方便的在該對象創建前和創建後進行某種操作,在開發過程中能更加的靈活多變。

發佈了44 篇原創文章 · 獲贊 26 · 訪問量 4353
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章