Spring:基於配置文件的創建對象的各種方式


在Spring3.0之前,Spring主要創建對象的方法是基於配置文件的,即在配置文件中為對象進行注冊,並且可以在配置文件當中為對象的字段或者稱之為屬性值進行賦值,接下來首先介紹基於配置文件的創建對象的方式。

 

1.1 基於配置文件的無參數構造函數的對象創建

package bjtu.wellhold.testSpring;

//當類當中沒有任何構造函數的時候,默認就是一個無參數的public的構造函數會被生成,如果一旦有任何一個構造函數
//則該默認的構造函數不會被生成。
public class Person {

    private String name;
    private Integer id;

    
    public String getName() {
        return name;
    }

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

    public Integer getId() {
        return id;
    }

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

    @Override
    public String toString() {
        return "Person [name=" + name + ", id=" + id + "]";
    }

}

這里有一點需要特別強調的,在只有無參數構造函數的情況下(或默認不寫),Spring在通過setter方式進行注入的時候,無論是否添加屬性的注入,Spring都會去尋找無參數的構造函數,通過這個無參數構造函數去進行注入,而在該Person的Pojo類當中,沒有顯式聲明任何構造函數(有參和無參的),在java當中JVM會默認為這個類生成一個無參數的構造函數,所以該類對於Spring是可用的。

 

<?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 class="bjtu.wellhold.testSpring.Person" id="person">
       <property name="name" value="LiuChunfu"></property>
       <property name="id" value="125"></property>
   </bean>

</beans>

這是Spring的配置文件,通過Pojo類當中的setter方法為對象的屬性進行了注入,並且創建了該Pojo對象的實例保存在Spring的IOC容器當中,等待其他類或者代碼塊進行調用。

 

package bjtu.wellhold.testSpring;

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

public class testUnit {

    public static void main(String[] args) {
        
        ApplicationContext cfg=new ClassPathXmlApplicationContext("Config.xml");
        Person person=(Person)cfg.getBean("person");
        System.out.println(person);
    }
}

這是測試代碼塊,可以看到打印出來的person的具體信息。

 

1.2 基於配置文件的帶參數構造函數的對象創建

package bjtu.wellhold.testSpring;

public class Person {

    private String name;
    private Integer id;
    
    public Person(String name, Integer id) {
        super();
        this.name = name;
        this.id = id;
    }
    
    @Override
    public String toString() {
        return "Person [name=" + name + ", id=" + id + "]";
    }

}

代碼當中提供了一個有參數的構造方法。

 

<?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 class="bjtu.wellhold.testSpring.Person" id="person">
        <constructor-arg name="id" value="123"></constructor-arg>
        <constructor-arg name="name" value="LiuChunfu"></constructor-arg>
    </bean>

</beans>

而在spring的配置文件當中,則是通過標簽<constructor-arg>去為對象注入屬性值,其中name字段對應的是pojo類構造方法當中的形參名稱。

測試代碼與1.1一樣,此處就不重復上代碼了。

 

 2.1 基於配置文件的靜態工廠方法的僅有無參數構造函數的對象創建

package bjtu.wellhold.testSpring;


public class Person {

    private String name;
    private Integer id;


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

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

    @Override
    public String toString() {
        return "Person [name=" + name + ", id=" + id + "]";
    }

}

在該pojo類當中,僅有默認不寫的無參數構造函數,所以我們要對其進行屬性值注入,僅能通過setter的方法進行注入,即和1.1的形式類似,但是這里我們是通過工廠的靜態方法的形式去進行的,所以這里我們還需要一個工廠類

package bjtu.wellhold.testSpring;

public class PersonStaticFactory {

    public static Person createPerson() {
        return new Person();
    }

}

這個工廠類僅有一個方法,就是creatPerson,即返回一個Person對象的實例,而這個實例化的方法調用的是Person類當中默認的無參數構造函數,那么這時候我們來思考一個問題,能為這個Person實例注入屬性值嘛?答案是肯定的,即與1.1當中的方法類似,通過標簽<property name="xxxx" value="yyy"></property>去通過Setter去進行注入即可。配置文件如下:

<?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="person" class="bjtu.wellhold.testSpring.PersonStaticFactory" factory-method="createPerson">
    <property name="id" value="123"></property>
    <property name="name" value="wellhold"></property>
 </bean>

</beans>

這里要簡單解釋一下,與1.1不同,這里是通過PersonStaticFacotory這個工廠類當中的CreatePerson方法去進行Person實例化的,在1.1當中則是通過Spring直接去實例化Person類的,方式是不同的。但是屬性值注入的方式則是一樣的。

測試模塊的代碼與1.1相同,這里不在重復。

 

 2.2 基於配置文件的靜態工廠方法的有參數構造函數的對象創建

package bjtu.wellhold.testSpring;

public class Person {

    private String name;
    private Integer id;
    
    public Person(String name, Integer id) {
        super();
        this.name = name;
        this.id = id;
    }
    
    public Person()
    {
        
    }
    
    @Override
    public String toString() {
        return "Person [name=" + name + ", id=" + id + "]";
    }

}

這個Pojo類當中含有兩個構造函數,一個是全參的構造函數,一個是無參的構造函數,我們就可以通過構造函數去為Person的實例進行屬性值注入,所以這里不再需要setter方法,並且我們的工廠類當中,應該也對應兩個構造函數的createPerson的方法,代碼如下:

package bjtu.wellhold.testSpring;

public class PersonStaticFactory {

    public static Person createPerson() {
        return new Person();
    }
    
    public static Person createPerson(Integer id,String name){
        return new Person(name,id);
    }

}

通過配置文件當中的<constructor-arg name="xxxx" value="yyyy"><constructor-arg>標簽去進行屬性值的注入,代碼如下:

 <bean id="person" class="bjtu.wellhold.testSpring.PersonStaticFactory" factory-method="createPerson">
        <constructor-arg name="id" value="123"></constructor-arg>
        <constructor-arg name="name" value="LiuChunfu"></constructor-arg>
 </bean>

這里要額外的提醒一點,在使用標簽<constructor-arg name="xxxx" value="yyyy"><constructor-arg>的時候,要與工廠類當中所有的靜態方法的形參對應,即要調用無參數的createPerson,則無需使用該標簽,要調用全參數的createPerson則需要將所有的參數都填上,否則會報錯誤。

 

 3.1 基於配置文件的工廠方法的無參數構造函數的對象創建

使用工廠方法與使用工廠靜態方法的唯一的區別就在於,因為工廠方法沒有設置成靜態的,所以再使用工廠之前,需要通過Spring去創建一個工廠的實例,才可以去調用該工廠實例的方法,創建工廠的實例相信從1.1當中就可以知道如何去創建,之后再通過已經被Spring管理起來的工廠實例去創建Person實例即可,其他的和工廠靜態方式沒有什么不同。

package bjtu.wellhold.testSpring;

public class Person {

    private String name;
    private Integer id;
    
    public Person(String name, Integer id) {
        super();
        this.name = name;
        this.id = id;
    }
    
    public Person()
    {
        
    }
    
    @Override
    public String toString() {
        return "Person [name=" + name + ", id=" + id + "]";
    }

}
package bjtu.wellhold.testSpring;

public class PersonStaticFactory {

    public static Person createPerson() {
        return new Person();
    }
    
    public static Person createPerson(Integer id,String name){
        return new Person(name,id);
    }

}
<?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="personFactory" class="bjtu.wellhold.testSpring.PersonFactory"></bean>

 <bean id="person" factory-bean="personFactory" factory-method="createPerson">
        <constructor-arg name="id" value="123"></constructor-arg>
        <constructor-arg name="name" value="wellhold"></constructor-arg>
 </bean>

</beans>

注意,與使用靜態方法不同的一點在於,在生成Person實例的時候,使用的標簽從class變成了factory-bean,這里要注意一下。除了使用構造函數進行屬性注入,也可以使用setter去進行屬性注入,這里就不在重復了,形式可以參考章節2當中的內容去自行進行嘗試。

 

本文主要參考了:http://www.cnblogs.com/LiuChunfu/p/5574383.html,並且通過自己的一些實踐,轉換成自己的思路和語言表述並記錄。


免責聲明!

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



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