1. 程式人生 > >Spring 學習之 二----Spring建立物件的三種方式

Spring 學習之 二----Spring建立物件的三種方式

    最近在系統的學習Spring,現在就Spring的一些知識進行總結。

    我們知道Spring是一個開放原始碼的設計層面的框架,他主要解決的是業務邏輯層與其他各層之間鬆耦合的問題。

    Spring 有三個核心:

    1.IOC 控制反轉

我們以前在A物件中建立B物件時,都是直接在A物件內部使用new B() 的方法建立物件,這樣下去,A和B有很強的的耦合性。那麼我們用到了Spring ,我們可以把建立物件和管理物件的控制前交給了Spring , 這樣就叫做控制反轉,也就說讓Spring 去管理和建立物件。

    2.DI 依賴注入

Spring在使用構造器方法和set注入扥方式建立物件時,總會將屬性自動設定為所需要的值的思想就是依賴注入的思想

    3.AOP 面向切面程式設計

我們知道OOP是面向物件程式設計,就是把世界萬物都抽象成一個搞物件。

AOP是對OOP的擴充套件和延伸,就是把一些物件共有的部分抽象成切面,然後對該切面進行一些許可權控制、事務管理、日誌管理等共性的操作的思想就是AOP思想。

    那麼如果使用Spring建立物件有哪幾種方式呢?

    有三種:

  1. 構造器方法
  2. 靜態工廠方法
  3. 實力工廠方法

前提條件:

1.建立一個web專案

2.引入Spring的jar包

    commons-io-2.4.jar
    commons-logging.jar
    spring-beans-3.2.8.RELEASE.jar
    spring-context-3.2.8.RELEASE.jar
    spring-core-3.2.8.RELEASE.jar
    spring-expression-3.2.8.RELEASE.jar

3.在src下建立applicationContext.xml檔案

    一.構造器方法

先建立一個Person類

package com.xljy.test.spring01;

public class Person {

	private String name;
	private int id;
	
	public String getName() {
		System.out.println("getName");
		return name;
	}
	public void setName(String name) {
		System.out.println("setName");
		this.name = name;
	}
	public int getId() {
		System.out.println("getId");
		return id;
	}
	public void setId(int id) {
		System.out.println("setId");
		this.id = id;
	}
	
	public String toString(){
		return "該person為id="+id+", name="+name+"";
	}	
}
這裡沒有寫構造方法,在java中如果沒有寫構造方法,會預設有一個構造方法,如果已經寫了一個無參構造方法,就不會預設建立無參構造方法。

所以此處我沒有寫任何一個構造方法,當然會預設建立一個無參的構造方法,下面我們就是用無參的構造方法來建立物件

下面是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">

    <bean class="com.xljy.test.spring01.Person" id="person">
        
    </bean>
    
</beans>

最簡單的applicationContext.xml的寫法,我們在此處聲明瞭person bean

下面是測試類

package com.xljy.test.spring01;

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

public class TestPersion01 {

	

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

這裡我們使用spring通過無參構造器來建立Person物件,toString()輸出的結果為:

該person為id=0, name=null

看穿件物件時預設將屬性設為初始值,int型別的初始值為0, String和引用型別的初始值為 null. 這就是依賴注入 DI的思想了;

並且在這裡觀察到setName()方法和setId()方法中的輸出語句都沒有輸出,說明現在使用無參構造器的時候還沒有用到set方法

假如我們在applicationContext.xml 配置檔案的 person bean中加入引數設定,如下:

<bean class="com.xljy.test.spring01.Person" id="person">
        <property name="name" value="LiuChunfu"></property>
        <property name="id" value="125"></property>
    </bean>

測試方法不變,執行後的結果為:

setName
setId

該person為id=125, name=LiuChunfu

說明物件在建立的時候呼叫了set方法。這是使用無參建構函式建立物件的方式,下面我在Person中再假如無參建構函式看看:

其他的不變,輸出結果為:

Person的無參建構函式
setName
setId

該person為id=125, name=LiuChunfu

又驗證了我們所想:Spring通過無參構造器建立物件時,如果有引數設定就會呼叫set方法。

下面我們來看看使用有參構造器是一個什麼樣的情形。

我們在Person類中增加了有參構造方法,其他的不變,Person如下:

package com.xljy.test.spring01;

public class Person {

	private String name;
	private int id;
	
	public Person(){
		System.out.println("Person的無參建構函式");
	}
	
	public Person(String name, int id){
		System.out.println("Person類的有參構造方法");
		this.name = name;
		this.id = id;
	}
	
	public String getName() {
		System.out.println("getName");
		return name;
	}
	public void setName(String name) {
		System.out.println("setName");
		this.name = name;
	}
	public int getId() {
		System.out.println("getId");
		return id;
	}
	public void setId(int id) {
		System.out.println("setId");
		this.id = id;
	}
	
	public String toString(){
		return "該person為id="+id+", name="+name+"";
	}	
}

其他的都不變,直接執行測試類得到的結果還是:

Person的無參建構函式
setName
setId

該person為id=125, name=LiuChunfu

說明還是通過無參構造器來建立物件,那麼如何通過有參構造器來建立物件呢?

修改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">

    <bean class="com.xljy.test.spring01.Person" id="person">
        <constructor-arg name="id" value="123"></constructor-arg>
        <constructor-arg name="name" value="LiuChunfu"></constructor-arg>
    </bean>
    
</beans>

其他的不變,執行測試類:

Person類的有參構造方法
該person為id=123, name=LiuChunfu

這回直接執行有參構造方法了,沒有使用set()方法。

二。靜態工廠方法建立物件

新建一個靜態工廠類方法 StaticPersonFactory

package com.xljy.test.spring01;

public class StaticPersonFactory {

	public static Person2 createPerson(){
		return new Person2();
	}
	
	public static Person2 createPerson(String name, int id){
		return new Person2(name, id);
	}
	
}

這裡既寫了無參構造器,也寫了有參構造器,方便看輸出,又定義了一個Person2類,如下:

package com.xljy.test.spring01;

public class Person2 {

	private String name;
	private int id;
	
	public Person2(){
		System.out.println("Person2的無參建構函式");
	}
	
	public Person2(String name, int id){
		System.out.println("Person2類的有參構造方法");
		this.name = name;
		this.id = id;
	}
	
	public String getName() {
		System.out.println("Person2---getName");
		return name;
	}
	public void setName(String name) {
		System.out.println("Person2--setName");
		this.name = name;
	}
	public int getId() {
		System.out.println("Person2---getId");
		return id;
	}
	public void setId(int id) {
		System.out.println("Person2--setId");
		this.id = id;
	}
	
	public String toString(){
		return "該Person2--person為id="+id+", name="+name+"";
	}	
}

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">

    <bean class="com.xljy.test.spring01.Person" id="person">
        <constructor-arg name="id" value="123"></constructor-arg>
        <constructor-arg name="name" value="LiuChunfu"></constructor-arg>
    </bean>
    
    <bean id="person2" class="com.xljy.test.spring01.StaticPersonFactory" factory-method="createPerson">
        
    </bean>
</beans>

這裡定義了person2的bean, 使用的靜態工廠方法建立Person2類,我們來看一下,測試類:

package com.xljy.test.spring01;

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

public class TestPersion01 {

	

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

我們把後面兩句註釋掉,只加載配置檔案,看輸出:

Person類的有參構造方法

Person2的無參建構函式

說明和Spring在初始化的時候配置檔案中的兩個bean都被建立了,靜態工廠方法也預設使用了無參構造方法。

三。例項工廠方法建立物件

首先建立例項工廠類方法:PersonFactory, 如下:

package com.xljy.test.spring01;

public class PersonFactory {

	public Person3 createPerson(){
		return new Person3();
	}
}

然後建立一個Person3類

package com.xljy.test.spring01;

public class Person3 {

	private String name;
	private int id;
	
	public Person3(){
		System.out.println("Person3的無參建構函式");
	}
	
	public Person3(String name, int id){
		System.out.println("Person3類的有參構造方法");
		this.name = name;
		this.id = id;
	}
	
	public String getName() {
		System.out.println("Person3--getName");
		return name;
	}
	public void setName(String name) {
		System.out.println("Person3--setName");
		this.name = name;
	}
	public int getId() {
		System.out.println("Person3-getId");
		return id;
	}
	public void setId(int id) {
		System.out.println("Person3--setId");
		this.id = id;
	}
	
	public String toString(){
		return "該Person3--person為id="+id+", name="+name+"";
	}	
}

定義applicationContext.xml 

<bean id="personFactory" class="com.xljy.test.spring01.PersonFactory">
        
    </bean>

    <bean id="person3" factory-bean="personFactory" factory-method="createPerson">

如下:

<?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="com.xljy.test.spring01.Person" id="person">
        <constructor-arg name="id" value="123"></constructor-arg>
        <constructor-arg name="name" value="LiuChunfu"></constructor-arg>
    </bean>
    
    <bean id="person2" class="com.xljy.test.spring01.StaticPersonFactory" factory-method="createPerson">
        
    </bean>
    
    <bean id="personFactory" class="com.xljy.test.spring01.PersonFactory">
        
    </bean>
    <bean id="person3" factory-bean="personFactory" factory-method="createPerson">
        
    </bean>
</beans>

如此,測試類:

package com.xljy.test.spring01;

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

public class TestPersion01 {

	

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

還是把後兩句註釋,我們來看初始化spring容器時,輸出如下:

Person類的有參構造方法
Person2的無參建構函式

Person3的無參建構函式

結果顯示:

Person類是通過構造器的方式建立的

Person2類是通過靜態工廠方法建立的

Person3類是通過實力工廠方法建立的

最後總結一下,spring建立物件的三種方式:

構造器

靜態工廠方法

例項工廠方法