Spring 學習筆記 一

 

Spring 學習筆記

Spring的疑問:

一、爲什麼需要Spring,其定位是什麼?

二、Spring有什麼好處,如何實現的?

       三、怎麼使用Spring?

 

Spring實現的優勢:

       無需實現框架指定的接口。Spring依賴注入,減少代碼間的依賴,便於重用。

       類與類之間的聯繫傳統方法通過構造輔助類來完成。Spring則將輔助類的事物從代碼中剝離到配置文件中

 

IOC(Inverse of control):

配置文件聯繫類與類,優勢之一就是IOCIoC,用白話來講,就是由容器控制程序之間的關係,而非傳統實現中,由程序代碼直接操控。這也就是所謂“控制反轉”的概念所在:控制權(其實是依賴關係)由應用代碼中轉到了外部容器,控制權的轉移,是所謂反轉。

 

DI(Dependency Injection):

所謂依賴注入,即組件之間的依賴關係由容器在運行期決定,形象的來說,即由容器動態的將某種依賴關係注入到組件之中。

 

概念:反向控制(IoC)和依賴注入(DI

一般來說,IoCDI代表同一個意思,就是:模塊不依賴框架,而是框架反向依賴模塊;模塊不主動去取得它所依賴的服務,而是由框架主動將它所需要的服務“注入”到模塊中。

還是有點繞,配合圖解來說明。“反”是對模塊而言,正向的直接依賴,變成了對目標對象的上層的依賴,變得更爲靈活。至於如下Copier的建立,則在構造中傳入兩個對象實例即可。

 


         

              From 《ioc從過去到現在》@baobao

 

“反向”還體現在開發順序上。在非DIP的例子中,下層模塊必須先於上層模塊完工,否則上層模塊將無法編譯。但是即便是這樣,總得有人將兩邊串聯起來。比如:在main中設置:

 

Copier copy = Copier(new KeboardReader(), new DisplayWriter())

 

這樣一來,還是回到了開始的時候,依賴關係只是遷移到了main裏。如果使用反射機制(反射的好處就是不用寫明類名,將類名寫到string中,這個可以放到文件裏):

 

Class readerClass = Class.forName("KeyboardReader");
        Class writerClass = Class.forName("DisplayWriter");
        Copier copier = new Copier((Reader) readerClass.newInstance(),
                                   (Writer) writerClass.newInstance());

 

這樣一來就是把依賴關係從編譯時刻遷移到了運行時(進一步就是類似反射機制,使用文件配置,這樣就可以脫離類)。使用Spring怎麼做(readerwriter配置在bean中):

 

     Copier copier = new Copier((Reader) BeanFactory.getBean("reader"),
                                   (Writer) BeanFactory.getBean("writer"));

 


      

也有問題:這種模式有什麼問題呢?最大的問題就是Copier必須依賴BeanFactory(或者Service Locator或其它名稱)的引用。由於BeanFactory是屬於框架的,因此這種耦合並不會增加應用程序模塊之間的耦合性。在許多情況下,模塊對框架的這種依賴性並不會帶來什麼問題。然而,如果我們希望我們的模塊能夠工作在許多不同的環境下,而不僅僅是工作於指定框架下,那麼這種對框架的依賴性可能成爲一種阻礙。

 

Spring的實際使用中,不只是這樣,類的構造也在託付給String,就是說直接調用beanFactory.getBean(“Copier”)可以得到你配置的實例。

 

<beans>
    <bean id="reader" class="KeyboardReader"/>
    <bean id="writer" class="DisplayWriter"/>
    <bean id="copier" class="Copier">
        <constructor-arg ref="reader"/>
        <constructor-arg ref="writer"/>
    </bean>
</beans>
 

這一次,依賴關係從main中終於脫離開來,直接寫入到了配置文件中,從模塊對框架的依賴,編程了框架也對模塊依賴(相互依賴?),這種框架倒過來依賴模塊的行爲就是IOC,控制反轉。

 

物極則反

事物的另一方面是,IoC框架在簡化了程序編寫的同時,大大複雜化了模塊的配置。各IoC框架的主要不同點,幾乎就在於如何配置模塊,如何讓框架知曉模塊之間的依賴關係。當配置的複雜程序達到一定程度時,其配置的難度、維護的複雜度會不亞於直接寫一段程序。IoC框架的最大問題也在於此。

 

Tip

       程序運行中,實例該在哪裏產生?Spring由容器管理這些實例,在運行中生成;傳統方法在類中生成實例,對外提供接口,這些差別帶來的影響有多大?Spring有多少優勢?

 

       Spring的對象注入通過接口(如HttpServletRequest的doGet、doPost傳遞的request、response)、設值(seTter方法)、構造(在創立時注入),這些方式保證的是:由容器(Spring)來管理這些類的對象的創建。通過注入的方式調用功能。

 

無侵入性(Reflection機制): 

Spring的設計時成爲一個高度擴展的無侵入框架,無需代碼中涉及Spring的專有類,即可將其納入Spring管理。EJB則設定了許多的接口與編碼規範,造成的後果是對代碼的遷移,重構都有很大苦難。

注意<value></value>代表一個空字符串,如果需要將屬性值設定爲null,必須使用<null/>節點。

 

org.springframework.beans org.springframework.contextspring IoC容器的基礎。

org.springframework.beans.factory.BeanFactory初始化和配置Bean,裝配它們之間的依賴關係。

ApplicationContext 是擴展了BeanFactory ,提供了更多的功能,在使用中Spring作者推薦是使用ApplicationContext

 

幾個重要的知識點:

 

(1) spring注入的方式

Setter注入和構造器注入。如果採用Setter方法注入,別忘了在類定義的時候加上setter方法,這一點開發者常常會忘掉,導致NullPointerException

 

(2)    自動裝配:

Spring提供多種自動裝配的功能,其中byName是最好用、最常用的。可以大大簡化bean的定義。例子

 

<beans default-autowire="byName">
 

比如我們定義了一個bean 類,它包含了master屬性,並且含有setMaster方法,那麼spring會自動在IoC容器中尋找名爲masterbean,然後調用setMastermaster對象賦值給master

 

(3)Bean的作用域

 

Singleton

Spring容器只存在一個共享的bean實例,默認的配置爲TRUE

 

<bean id="example" class="com.yz.bean.Example"/>
 

Prototype每次對bean的請求都會創建一個新的bean實例。

 

<bean id="example" class="com.yz.bean.Example" singleton=”false”/>
 

兩者如何選擇?原則:所有有狀態的bean都使用Prototype作用域,而對無狀態的bean則應該使用singleton作用域。

 

(4) 熟悉Spring的配置文件xmlbean的定義,有助於我們靈活地定義bean

Bean的定義的格式基本如下:

 

<bean id="example" class="com.yz.bean.Example"/>
 

id唯一標識該bean,要使用某個bean,只需在容器中通過id獲得之,就可以獲得它的一個實例。

Bean的屬性定義如:<properyt name=””>

其屬性值可以爲:

l         其它bean

ref bean=

ref local=

l         集合

<list> <set> <map> <props>

l         數字,字符串。

 

(6) bean定義中的繼承關係,使用這種繼承關係同樣可以簡化bean的定義,實際開發中經常被使用。

如果你希望你的java bean的實例能繼承另外一個java bean的配置信息。那麼你在定義該bean的時候要使用parent屬性。

 

<bean id="childExample" class="com.yz.bean.ChildExample" parent="example"></bean>
 

儘管這兩個bean實際上沒有類的繼承關係,也可以使用parent屬性。這種parent屬性的方式實際上提供了模板的形式。

 

(7)  PropertyPlaceholderConfigure

 

用途:將spring中分佈在不同的xml文件的一些屬性值統一到一個文件來維護。這樣可以提高我們程序的維護性,我們在實際開發中經常使用它。

 

 

  <bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="location" value="/com/yz/bean/common.properties"/>
    </bean>
    <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
 

    


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章