溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Spring工廠的反射和配置文件源碼分析

發(fā)布時(shí)間:2023-04-07 09:39:41 來源:億速云 閱讀:86 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹了Spring工廠的反射和配置文件源碼分析的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Spring工廠的反射和配置文件源碼分析文章都會(huì)有所收獲,下面我們一起來看看吧。

    反射和配置文件

    學(xué)習(xí) Spring 的時(shí)候,雖然可以知道是通過反射和配置文件的方式來獲取 JavaBean 對象,但是一直沒有機(jī)會(huì)自己嘗試一次,探究以下內(nèi)部原理,雖然有人推薦閱讀源碼,但是可能還是感覺學(xué)的不好,一直沒有嘗試過?,F(xiàn)在剛好學(xué)習(xí)設(shè)計(jì)模式剛好遇到了這部分的內(nèi)容了,感覺自己對這個(gè)有了一個(gè)較好的理解了。

    設(shè)計(jì)模式中,為了滿足開閉原則,大都引入了抽象層,如工廠方法模式、抽象工廠模式等。客戶端針對抽象層編程,而在程序運(yùn)行的時(shí)候再指定其子類,根據(jù)里氏代換原則和面向?qū)ο蟮亩鄳B(tài)性,子類對象再運(yùn)行時(shí)將覆蓋父類對象。如果需要對系統(tǒng)進(jìn)行擴(kuò)展,只需要修改子類類名即可。在具體實(shí)現(xiàn)時(shí),通過引入配置文件可以使得用戶再不修改客戶端任何代碼的前提下增加或替換子類,

    其基本實(shí)現(xiàn)過程過程為:

    1. 客戶端針對抽象層編程,客戶端代碼中不能出現(xiàn)具體的類名,即客戶端不直接實(shí)例化對象。

    2. 引入純文本格式的配置文件,通常是 XML 文件,將具體類類名存儲(chǔ)在配置文件中。

    3. 通過 DOM(Document Object Model,文檔對象模型)、SAX(SimpleAPI for XML)等 XML 解析技術(shù)獲取存儲(chǔ)在配置文件中類名。

    4. 在客戶端代碼中通過反射機(jī)制根據(jù)類名創(chuàng)建對象,用反射所創(chuàng)建的對象代替父類對象的引用,程序運(yùn)行時(shí),將調(diào)用子類方法來實(shí)現(xiàn)業(yè)務(wù)功能。

    5. 如果需要擴(kuò)展功能,只需要添加一個(gè)新的子類繼承抽象父類,再修改配置文件,重新運(yùn)行程序即可;如果需要替換功能,只需要另一個(gè)子類類名替換存儲(chǔ)再配置文件中的原有子類類名。無論是擴(kuò)展還是替換都無須修改既有類庫和客戶端源碼,完全符合開閉原則。

    Talk is cheap, show me the code.

    直接通過代碼來理解上面的內(nèi)容吧。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
    	<bean>com.reflect.Dog</bean>
    </beans>

    測試實(shí)體類

    package com.reflect;
    
    public class Dog {
    	private String name;
    	private Integer age;
    	
    	public Dog() {}
    	
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public Integer getAge() {
    		return age;
    	}
    	public void setAge(Integer age) {
    		this.age = age;
    	}
    
    	@Override
    	public String toString() {
    		return "Dog [name=" + name + ", age=" + age + "]";
    	}
    }

    對象工廠類(類似Spring工廠的簡單實(shí)現(xiàn))

    package com.reflect;
    
    import javax.xml.parsers.DocumentBuilderFactory;
    import org.w3c.dom.*;
    
    public class Factory {
    	public static Object getBean() {
    		try {
    			Document doc = DocumentBuilderFactory
    					.newInstance()
    					.newDocumentBuilder()
    					.parse("src/beans.xml");
    			
    			//獲取包含類名的文本節(jié)點(diǎn)
    			NodeList nodeList  = doc.getElementsByTagName("bean");
    			Node node = nodeList.item(0).getFirstChild();
    			String name = node.getNodeValue();
    			
    			//通過類名生成實(shí)例對象并將其返回
    			Class<?> clazz = Class.forName(name);
    			return clazz.newInstance();
    		} catch (Exception e) {
    			e.printStackTrace();
    			return null; 
    		} 
    	}
    }

    測試類

    package com.reflect;
    
    public class Test {
    	public static void main(String[] args) {
    		Dog dog = null;
    		dog = (Dog)Factory.getBean();
    		dog.setName("小黑");
    		dog.setAge(12);
    		System.out.println(dog.toString());
    	}
    }

    項(xiàng)目目錄結(jié)構(gòu)
    注意這里需要使用 dom4j 的jar包,下載導(dǎo)入即可!

    Spring工廠的反射和配置文件源碼分析

    運(yùn)行結(jié)果

    Spring工廠的反射和配置文件源碼分析

    現(xiàn)在需求變了,不想使用 Dog 類,而要使用 HuntDog 類,只要增加 HuntDog 類, 并繼承 Dog 類即可,項(xiàng)目源碼不需要改動(dòng),滿足開閉原則。

    package com.reflect;
    
    public class HuntDog extends Dog {
    	private String name;
    	private Integer age;
    	
    	public HuntDog() {}
    	
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public Integer getAge() {
    		return age;
    	}
    	public void setAge(Integer age) {
    		this.age = age;
    	}
    
    	
    	@Override
    	public String toString() {
    		return "HuntDog [name=" + name + ", age=" + age + "]";
    	}
    
    	public void say() {
    		System.out.println("Hello, I am HuntDog: "+this.toString());
    	}
    }

    修改 XML 如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans>
    	<bean>com.reflect.HuntDog</bean>
    </beans>

    修改后的運(yùn)行結(jié)果

    Spring工廠的反射和配置文件源碼分析

    關(guān)于“Spring工廠的反射和配置文件源碼分析”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“Spring工廠的反射和配置文件源碼分析”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI