注:本文來自於網絡或者老師的總結資料,本人僅為摘錄,想了解更多相關資料,可以關注:
http://blog.csdn.net/pu_xubo565599455
什么是spring框架?
Spring 是一個開源框架,是一種整合性的框架,是為了解決企業應用程序開發復雜性而創建的。框架的主要優勢之一就是其分層架構,分層架構允許您選擇使用哪一個組件,同時為 J2EE 應用程序開發提供集成的框架。至03年spring框架發布以來到現在pring框架已經發展成JavaEE開發中的非常重要的一個框架。雖然還是有公司采用自己的方式來處理代碼間的耦合問題,但是他們采用的方式依舊是Spring框架的基礎,即:工廠模式與服務定位器模式等。
Spring是為企業應用開發提供的一個輕量級解決方案,包括:基於依賴注入的核心機制,基於AOP的聲明式事務(聯想下編程式事務),整合多種持久層技術的整合,整合很多優秀的WEB MVC框架等。Spring是致力於JavaEE應用各層的解決方案,而不是單單針對某一層。Spring貫穿表現層,業務層,持久層,但是Spring並不想取代那些已有的框架,而是以高度的開發性與它們無縫整合。
spring框架優點?
1、 低侵入式設計,代碼的污染極低。
2、 Spring容器降低了業務對象替換的復雜性,提高了組件之間的解耦。
3、 Spring的AOP支持允許將一些通用任務如:安全,事務,日志等進行集中式處理,從而提供了更好的復用。
4、 Spring的ORM和DAO提供了與第三方持久化框架的良好整合,並簡化了底層的數據庫訪問。
5、 Spring的高度開發性,並不強制應用完全依賴於Spring,開發者可自由選擇Spring框架的部分或全部。
spring--IOC
IOC 即 Inversion Of Control,控制反轉或者稱之為依賴注入。IoC 不是一種技術,只是一種思想,一個重要的面向對象編程的法則,它能指導我們如何設計出松耦合、更優良的程序。在工作中, JAVA實例的調用者通過new關鍵字來創建被調用者的JAVA實例,程序高度耦合,效率低下,真實的應用極少使用這種方式,一般是初學者最喜歡。有了IoC容器后,把創建和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,所以對象與對象之間是 松散耦合,這樣也方便測試,利於功能復用,更重要的是使得程序的整個體系結構變得非常靈活。依賴注入是目前最優秀的解耦方式,依賴注入讓Spring的Bean以配置文件組織在一起,而不是以硬編碼的方式耦合在一起。
依賴注入通常有如下兩種方式:
設值注入:IOC容器使用屬性的Setter方法來注入被依賴的實例。
構造注入:IOC容器使用構造器來注入被依賴的實例。
設值注入:
設值注入是指IOC容器使用屬性的Setter方法來注入被依賴的實例。這種注入方式簡單、直觀,因而在Spring的依賴注入里大量使用。
例外:
注意:Spring推薦面向接口編程,可以更好的讓規范和實現分離,從而提供更好的解耦,對於一個JAVAEE應用,不管是DAO組件,還是業務邏輯組件,都應該先定義一個接口,該接口定義組件應該實現的功能,但是功能的實現則由其實現類提供。
我們先定義2個接口,如:
然后,分別實現其實現類,如:
最后,我們在applicationContext.xml的<beans></beans>中分別配置2個JAVABEAN實例,並配置其關系管理。如:
在配置文件中,Spring配置Bean實例通常會指定2個屬性:
Id:指定該Bean的唯一標識,程序通過ID屬性值來訪問該BEAN實例。
Class:指定該BEAN的實現類,此處不可再用接口,必須使用實現類,Spring容器會使用XML解析器讀取該屬性值,並利用反射來創建該實現類的實例。
從上面的示例中,可以分析出,依賴注入以配置文件管理BEAN實例之間的耦合,讓BEAN實例之間的耦合從代碼層次分離出來,依賴注入是一種優秀的解耦方式。
分析得到SpringIOC容器的3個基本要點:
1、 應用程序的各組件面向接口編程。面向接口編程可以將各組件之間的耦合提示到接口層次,從而有利於項目后期的發展。
2、 應用程序的各組件不再由程序主動產生,而是由Spring容器來負責產生、並初始化。
3、 Spring采用配置文件、或Annotation來管理Bean的實現類、依賴關系,Spring容器則根據配置文件、利用反射來創建實例,並為之注入依賴關系。
構造注入:
前面我們介紹,通過setter方法為目標Bean注入依賴關系的方式,被稱為設值注入:另外還有一種注入方式,這種方式在構造實例時,已經為其完成了依賴關系的初始化。這種利用構造器來設置依賴關系的方式,被稱之為構造注入。
import com.lovo.beans.CardInfoT;
import com.lovo.dao.ICardDao;
import com.lovo.service.ICardService;
public class CardServiceImpl implements ICardService {
private ICardDao cardDaoImpl;
//默認的構造器,如果要設置有參構造,需要先顯示執行無參構造
public CardServiceImpl(){
}
/**
* 構造注入所需的帶參數的構造器
* @param cardDao
*/
public CardServiceImpl(ICardDao cardDao){
this.cardDaoImpl = cardDao;
}
public void saveCard(CardInfoT card) {
// TODO Auto-generated method stub
cardDaoImpl.saveCard(card);
}
}
applicationContext.xml中添加配置為:
<!-- 由spring容器創建實例化對象,並管理對象之間的關系 -->
<bean id="cardDaoImpl" class="com.lovo.dao.impl.CardDaoImpl"></bean>
<!-- spring構造注入-->
<bean id="cardServiceImpl" class="com.lovo.service.impl.CardServiceImpl">
<!-- 使用構造注入,為 cardServiceImpl實例注入cardDaoImpl實例-->
<constructor-arg ref="cardDaoImpl"></constructor-arg>
</bean>
兩種注入方式的對比:
Spring同時支持兩種依賴注入方式:設置注入和構造注入。兩種注入方式,並沒有絕對的好壞之分,只是適應的場景有所不同。
相比之下,設置注入具有如下優點:
1、 與傳統的JavaBean的寫法更相識,程序開發人員更容易理解、接受、通過setter方式設定依賴關系顯得更加直觀、自然。
2、 對於復雜的依賴關系,如果采用構造注入,會導致構造器過於臃腫,難以閱讀。Spring在創建Bean實例時,需要同時實例化其依賴的全部實例,因而導致性能下降。而使用設置注入,則可以避免。
3、 尤其是在某些屬性可選的情況下,多參數的構造器更加笨重。
當然,構造注入也不是絕對不如設值注入,某些特定的場合,構造更適合。構造也有如下優點:
1、 構造注入可以在構造器中決定依賴關系的注入順序,優先依賴的優先注入,常常需要依賴於Datasource的注入。采用構造注入,可以在代碼中清晰地決定注入順序。
2、 對於依賴關系無須變化的Bean,構造注入更有用處。因為沒有setter方法,所有的依賴關系全部在構造器中設定,因此,無須擔心后續的代碼對依賴關系產生破壞。
3、 依賴關系只能在構造器中設定,則只有組件的創建者才能改變組件的依賴關系。對組件的調用者而言,組件內部的依賴關系完全透明,更符合高內聚的原則。
建議采用以設值注入為主,構造注入為輔的注入策略。對於依賴關系無須變化的注入,盡量采用構造注入;而其他的依賴關系的注入,則考慮采用設值注入。
Spring 容器
Spring提供了兩個核心接口:BeanFactory和ApplicationContext,其中applicationContext是BeanFactory的子接口。他們都可代表Spring容器,Spring容器是生成Bean實例的工廠,並管理容器中的Bean。Bean是Spring管理的基本單位,在基於Spring的JavaEE應用中,所有的組件都被當成Bean處理,包括數據源、Hibernate的SessionFactory、事務管理器等。
BeanFactory:
Spring容器最基本的接口就是BeanFactory,該接口負責配置、創建,管理Bean,它有一個子接口;AppcationContext,也被稱為Spring上下文。Spring容器還負責管理Bean與Bean之間的依賴關系。
調用者只需使用getBean()方法即可獲得指定Bean的引用,無須關心Bean的實例化過程。
BeanFactory有一個常見的實現類:org.springframework.beans.factory.xml.XmlBeanFactory類。
ApplicationContext是BeanFactory的子接口,對於大部分JavaEE應用而言,使用它作為Spring容器更方便。其常見實現類是:FileSystemXmlApplicationContext、ClassPathXmlApplicationContext和AnnotataionConfigApplicationContext。如果在web應用中使用Spring容器,通常有XmlWebApplicationContext、AnnotatioinConfigWebApplicationContext兩個實現類。
大部分的JavaEE應用,可以在啟動WEB應用時自動加載ApplicationContext實例,接受Spring管理的Bean無須知道ApplicationContext的存在,一樣可以利用ApplicationContext的管理。對於獨立的應用程序,也可通過如下方法來實例化BeanFactory。
1、
//搜索當前文件路徑下的beans.xml文件創建Resource對象
InputStreamResource isr = new FileSystemResource(“beans.xml”);
//以Resource對象作為參數,創建BeanFactory對象
XmlBeanFactory factory = new XmlBeanFactory(isr);
或者采用:
2、
//搜索類加載路徑,以類加載路徑下的beans.xml文件創建Resource對象
ClassPathResource res = new ClassPathResource(“beans.xml”);
//以Resource對象作為參數,創建BeanFactory對象
XmlBeanFactory factory = new XmlBeanFactory(res);
如果需要同時加載多個XML配置文件,則可以采用如下方式:
//搜索CLASSPATH路徑,以CLASSPATH路徑下的applicationContext.xml、Bean.xml、Service.xml文件創建ApplicationContext
ApplicationContext appContext = new ClassPathXmlApplicaation(new String[“beans.xml”,”service.xml”]);
ApplicationContext:
大部分時候,我們都不會使用BeanFactory實例作為Spring 容器,而是使用ApplicationContext實例作為容器,因此我們也把Spring容器稱為Spring上下文。ApplicationContext是BeanFactory接口的子接口,它增強了BeanFactory的功能。
ApplicationContext允許以聲明式方式操作容器,無須手動創建它。可利用如ContextLoader的支持類,在WEB應用啟動時自動創建ApplicationContext。當前,也可以采用編程方式創建ApplicationContext.
BeanFactory與ApplicationContext實例化容器中Bean的時機不同,前者等到程序需要Bean實例時才創建,而后者在容器創建ApplicationContext實例時,會預初始化容器中的全部Bean。
因為采用ApplicationContext作為Spring容器,創建容器時會同時創建容器中所有singleton作用域Bean,因此可能需要更多的系統開銷。但一旦創建成功,應用后面的響應速度就會更快,因此,對於普通的JavaEE應用,推薦使用ApplicationContext作為Spring容器。
實際上Spring允許singleton作用的Bean指定lazy-init=”true”,該屬性將改變singleton Bean實例的默認行為,強制取消該Bean實例預初始化,則該Bean將不會隨着ApplicationContext啟動而預實例化。