《Java Spring框架》SpringXML配置詳解


Spring框架作為Bean的管理容器,其最經典最基礎的Bean配置方式就是純XML配置,這樣做使得結構清晰明了,適合大型項目使用。Spring的XML配置雖然很繁瑣,而且存在簡潔的注解方式,但讀懂XML配置文件對我們來說依然很重要,尚且對於老系統維護必不可少的面對XML配置。

下面通過案例來理解XML配置。

案例:(一個基礎的Bean)

public class Pet {
    private String petType;
    private String color ;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getPetType() {
        return petType;
    }

    public void setPetType(String petType) {
        this.petType = petType;
    }

    public String toString(){
        return"petType: "+petType+" color: "+color;
    }
}
public class User {
    String id;
    String name;
    String passWord;

    Pet pet;

    public Pet getPet() {
        return pet;
    }

    public void setPet(Pet pet) {
        this.pet = pet;
    }

    public User(){
        System.out.println("spring 需要一個空參構造!");
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", passWord='" + passWord + '\'' +
                ", pet=" + pet +
                '}';
    }

    public void init(){
        System.out.println("User初始化執行init方法!");
    }

    public void userDestroy(){
        System.out.println("userDestroy方法被執行!");
    }
}
import com.bing.tao.bean.User;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloSpring {

    /**
     * IOC的反轉:創建對象這份工作由我們自己執行反轉給spring幫我們執行;
     * IOC的控制:就是由spring幫我們負責創建銷毀對象,掌控對象的生命周期等,我們在需要使用對象的時候跟Spring申請即可;
     * IOC是一種編程思想,也是一種新的設計模式,它需要DI(依賴注入)技術的支持;
     * spring是一個容器,它將幫我們管理對象
     */
    @Test
    public void Test1(){
        //根據spring配置文件獲取容器對象
        //ApplicationContext 配置的所有bean都會在容器創建的時候被創建出來
        //如果配置的bean較多,那么在創建容的時候,會產生內存過大的問題;這種情況在機器硬件性能較為落后的時候體現的比較明顯;
        //延遲加載 true就是創建容器時不加載配置的bean對象,在獲取的時候才創建;
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user= (User) applicationContext.getBean("user");
        System.out.println("user: "+user);
        //通過getBean獲取配置好的user對象(程序員向spring容器要對象)
        user= applicationContext.getBean(User.class);
        System.out.println("user: "+user);
        applicationContext.close();
    }
}

重要的配置:(創建一個名字叫:applicationContext.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">

    <!-- spring管理bean的XML,一個bean標簽表示一個bean。-->
    <!-- name屬性給bean取名,代碼中可以通過:applicationContext.getBean("user"); 獲取class-->
    <!-- class:是被管理對象的全包名,spring會通過這個包名來創建對象 -->
    <!-- scope 屬性,控制對象的單例還是多例,prototype多例-->
    <!-- 在web環境下,如果scope屬性為request 那么這個對象被創建出來 他的生命周期會與request請求一致-->
    <!-- session 同理 ,生命周期與session一致 -->
    <!-- lazy-init 延遲加載,獲取bean 的時候才加載 ,否則在創建容器是就會加載bean。-->
    <!-- 初始化方法:init-method,spring創建bean的時候會執行-->
    <!-- 銷毀bean方法:destroy-method spring銷毀bean的時候會執行-->
    <bean name = "user" class="com.bing.tao.bean.User" scope="singleton" lazy-init="false" init-method="init" destroy-method="userDestroy">
        <!-- property 標簽,是用於bean內部屬性初始化值使用的。-->
        <!-- name 對應bean的變量名,value 就是初始值。-->
        <property name="id" value="1"></property>
        <property name="name" value="蕾蕾"></property>
        <property name="passWord" value="123456"></property>
        <!-- 引用類型的初始化 -->
        <property name="pet" ref="pet"></property>
    </bean>

    <!-- 將pet對象交給spring管理,並注入值類型 -->
    <bean name = "pet" class="com.bing.tao.bean.Pet">
        <property name="petType" value="二哈"></property>
        <property name="color" value="灰灰"></property>
    </bean>
</beans>

運行結果:

配置文件,已經將標簽含義說明清楚。補充一點:如果是多例則spring不在管理bean而是交給你管理,銷毀方法將不再執行。

 

Spring XML配置如何支持構造函數和復雜數據類型(List等):

修改User類:

public class User {
    String id;
    String name;
    String passWord;

    Pet pet;

    public Pet getPet() {
        return pet;
    }

    public void setPet(Pet pet) {
        this.pet = pet;
    }

    public User(){
        System.out.println("spring 需要一個空參構造!");
    }

    public User(String name, Pet pet) {
        System.out.println("打印構造方法1:name :"+name +"pet:"+pet);
        this.name = name;
        this.pet = pet;
    }

    public User(Pet pet,String name) {
        System.out.println("打印構造方法2:name :"+name +"pet:"+pet);
        this.name = name;
        this.pet = pet;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", passWord='" + passWord + '\'' +
                ", pet=" + pet +
                '}';
    }

    public void init(){
        System.out.println("User初始化執行init方法!");
    }

    public void userDestroy(){
        System.out.println("userDestroy方法被執行!");
    }
}

新增測試方法:

import com.bing.tao.bean.MyCollection;
import com.bing.tao.bean.User;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloSpring2 {

    @Test
    public void Test1(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext_Injection.xml");
        User user= (User) applicationContext.getBean("user");
        System.out.println(user);
        System.out.println("-----------------分割線-----------------");
        MyCollection myCollection= (MyCollection) applicationContext.getBean("myCollection");
        System.out.println(myCollection);
    }
}

新增配置文件:applicationContext_Injection.xml

配置內容如下:

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

    <!-- 構造方法注入 -->
    <bean name="user" class="com.bing.tao.bean.User">
        <!-- name 調用構造方法的參數名稱 value 是注入值類型 ref 注入引用類型 -->
        <!-- type 是指定參數的類型 -->
        <!-- index 是指定參數的 -->
        <constructor-arg name="name" value="老王" type="java.lang.String" index="1"/>
        <constructor-arg name="pet" ref="pet"/>
    </bean>

    <!-- 將pet對象交給spring管理,並注入值類型 -->
    <bean name = "pet" class="com.bing.tao.bean.Pet">
        <property name="petType" value="二哈"></property>
        <property name="color" value="灰灰"></property>
    </bean>

    <!-- 復雜類型注入 -->
    <bean name="myCollection" class="com.bing.tao.bean.MyCollection">
        <!-- Array -->
        <property name="array">
            <array>
                <value>123</value>
                <value>abc</value>
                <ref bean="pet"></ref>
            </array>
        </property>

        <!-- List -->
        <property name="list">
            <list>
                <value>456</value>
                <value>def</value>
                <ref bean="user"></ref>
            </list>
        </property>

        <!-- Set -->
        <!-- 當只有一個值得時候,可以簡寫成一下方式。 -->
        <property name="set" value="789"></property>

        <!-- Map -->
        <property name="map">
            <map>
                <entry key="root" value="123"></entry>
                <entry key="admin" value="456"></entry>
                <entry key-ref="user" value-ref="pet"></entry>
            </map>
        </property>

        <!-- properties -->
        <property name="prop">
            <props>
                <prop key="name">老李</prop>
                <prop key="age">25</prop>
            </props>
        </property>
    </bean>
</beans>

運行結果:

看到這邊,大部分人都會覺得,每一個Bean都要這么操作一下,這么復雜,還不如直接寫代碼呢。

接下來,我們來簡化配置。

先來簡化配置:(新建一個配置文件:applicationContext_annotation.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"
       xmlns:contest="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    <!-- 將包 com.bing.tao.bean 下的Bean都交給Spring -->
    <contest:component-scan base-package="com.bing.tao.bean"></contest:component-scan>
</beans>

將User修改成:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @Component 用於標記該bean需要Spring實例化。
 * @Scope 標簽用於標記該bean是單例還是多例,singleton表示單例,prototype多例。
 */
@Component("user")
@Scope(scopeName = "singleton")
public class User {

    /**
     * @Value標簽可以將括號中的值注入到Spring生成的Bean中
     */
    @Value("1")
    String id;
    @Value("蕾蕾")
    String name;
    @Value("123")
    String passWord;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public String toString(){
        return"name: "+name+" id: "+id;
    }

    //構造后調用
    @PostConstruct
    public void init(){
        System.out.println("User初始化執行init方法!");
    }

    //銷毀前調用
    @PreDestroy
    public void userDestroy(){
        System.out.println("userDestroy方法被執行!");
    }
}

創建一個測試方法:

import com.bing.tao.bean.User;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloSpring3 {

    @Test
    public void Test1(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext_annotation.xml");
        //通過getBean獲取配置好的user對象(程序員向spring容器要對象)
        User user= (User) applicationContext.getBean("user");

        System.out.println(user);
        //scope="singleton" 是單例下才能出發銷毀bean方法,如果是多例則spring不在關聯bean而是交給你管理。
        applicationContext.close();
    }
}

運行結果:

這樣就可以批量設置模式一樣的Bean結構了。XML的配置就可以很好的簡化。同時還倒逼了目錄結構的整齊。

總結來源:http://www.sikiedu.com/ 網站學習。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM