縱觀現在互聯網行業,java的地位依然不可動搖,因為java擁有着的眾多開發人員和適用性廣,技術與解決技術大部分開源等特點,因此java依然是眾多眾多開發行業作為互聯網開發的首選,而說到開發,我們就不等不說一下近年來最火爆的那些開源框架!
首先我們來看一下那些曾經以及現在仍然火爆的框架有哪些:
注:因為今天主要目的是講解Spring,所以其他框架就先不詳細講解了,我改天會單開個框架專欄給大家講解
傳統行業:
SSH(Spring,Struts2,Hibernate)
作為傳統行業的經典,可以說SSH框架組合現在還有很多互聯網行業在用到,當然,之所以還在用,是因為有很多傳統項目並沒有下架,所有說很多互聯網行業依然需要程序員來對這些傳統業務進行維護,那么作為學習java的我們,就必然要對這個框架有所了解和應用!
進階版:
SSJ(Spring,Struts2,Spring Data JPA)
之所以說這個SSJ的框架組合是SSH的進階版是因為它的持久城框架從hibernate換為了Spring Data JPA,而Spring Data JPA實際上是Spring基於hibernate開發的一個JPA框架,目的是簡化持久層代碼,dao層只需要定義接口即可,也就是持久層面向接口開發
它歸屬於阿帕奇公司的一個叫做Spring Data的項目,而Spring Data的目的則是為了簡化構建基於 Spring 框架應用的數據訪問技術,包括非關系數據庫、Map-Reduce 框架、雲數據服務等等;另外也包含對關系數據庫的訪問支持。換句話說就是阿帕奇公司希望用Spring Data統一市面上所有的持久層框架(野心很大的說)。
至於為什么說這個還僅是進階版,是因為Struts2的存在,Struts2確實層經風靡一時,優點眾多,但可惜自從業內頻繁爆出Struts2存在着嚴重的安全漏洞,有着數據丟失容易被攻擊的消息,而且京東曾因此遭受重大損失后,就慢慢的讓出了業務層一哥的位置,而京東的痛下決心替換Struts2的行為,更是加速了Struts2的沒落,而改由更棒的Spring MVC所替代。
新興互聯網行業:
SSM(Spring MVC,Spring,MyBatis)
SSM框架依然都是由Apache公司提供的開源,免費的框架,具有着輕量級,依賴關系解耦,面向接口,程序穩定等優良特點。
縱觀傳統和新興,我們能發現,一直有一個身影在其中,而它就是Spring,一款由Apache公司推出,Rod Johnson(spring之父)開發的優秀的免費輕量級開源框架。下面就讓我們一起來了解一下。
Spring簡介
Spring是分層的Java SE/EE應用 full-stack輕量級開源框架,以IoC(Inverse Of Control:反轉控制)和AOP(Aspect Oriented Programming:面向切面編程)為內核,提供了展現層Spring MVC和持久層Spring JDBC以及業務層事務管理等眾多的企業級應用技術,還能整合開源世界眾多著名的第三方框架和類庫,逐漸成為使用最多的Java EE企業應用開源框架。
Spring的優勢
方便解耦,簡化開發
通過Spring提供的IoC容器,可以將對象間的依賴關系交由Spring進行控制,避免硬編碼所造成的過度程序耦合。用戶也不必再為單例模式類、屬性文件解析等這些很底層的需求編寫代碼,可以更專注於上層的應用。
AOP編程的支持
通過Spring的AOP功能,方便進行面向切面的編程,許多不容易用傳統OOP實現的功能可以通過AOP輕松應付。
聲明式事務的支持
可以將我們從單調煩悶的事務管理代碼中解脫出來,通過聲明式方式靈活的進行事務的管理,提高開發效率和質量。
方便程序的測試
可以用非容器依賴的編程方式進行幾乎所有的測試工作,測試不再是昂貴的操作,而是隨手可做的事情。
方便集成各種優秀框架
Spring可以降低各種框架的使用難度,提供了對各種優秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。
降低JavaEE API的使用難度
Spring對JavaEE API(如JDBC、JavaMail、遠程調用等)進行了薄薄的封裝層,使這些API的使用難度大為降低。
Java源碼是經典學習范例
Spring的源代碼設計精妙、結構清晰、匠心獨用,處處體現着大師對Java設計模式靈活運用以及對Java技術的高深造詣。它的源代碼無意是Java技術的最佳實踐的范例。
Spring的體系結構
spring的開發包
官網:http://spring.io/
下載地址:
http://repo.springsource.org/libs-release-local/org/springframework/spring
解壓:(Spring目錄結構:)
* docs :API和開發規范.
* libs :jar包和源碼.
* schema :約束.
之前我們說了spring的重多優點,而這些優點是由Spring提供的幾個強化功能實現的,而這幾個功能也是Spring的極大亮點,需要我們關注,因為這些亮點幾乎是我們作為程序員所應知應會的,下面我們就來看看這幾個亮點分別是什么:
控制反轉 - - IOC(方便解耦)
依賴注入 - - DI
切面編程 - - AOP
控制反轉:
說道控制反轉的解耦型,我們就需要知道一個問題,即什么是程序的耦合性?
什么是程序的耦合
我們在開發中,會寫很多的類,而有些類之間不可避免的產生依賴關系,這種依賴關系稱之為耦合。
有些依賴關系是必須的,有些依賴關系可以通過優化代碼來解除的。請看下面的示例代碼:
/** * 客戶的業務層實現類 * @author zhy */
public class CustomerServiceImpl implements ICustomerService { private ICustomerDao customerDao = new CustomerDaoImpl(); }
上面的代碼表示:業務層調用持久層,並且此時業務層在依賴持久層的接口和實現類。如果此時沒有持久層實現類,編譯將不能通過。這種依賴關系就是我們可以通過優化代碼解決的。
再比如:
下面的代碼中,我們的類依賴了MySQL的具體驅動類,如果這時候更換了數據庫品牌,我們需要改源碼來修改數據庫驅動。這顯然不是我們想要的。
public class JdbcDemo1 { /** * JDBC操作數據庫的基本入門中存在什么問題? * 導致驅動注冊兩次是個問題,但不是嚴重的。 * 嚴重的問題:是當前類和mysql的驅動類有很強的依賴關系。 * 當我們沒有驅動類的時候,連編譯都不讓。 * 那這種依賴關系,就叫做程序的耦合 * * 我們在開發中,理想的狀態應該是: * 我們應該盡力達到的:編譯時不依賴,運行時才依賴。 * @param args * @throws Exception */
public static void main(String[] args) throws Exception { //1.注冊驅動 //DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver"); //2.獲取連接 //3.獲取預處理sql語句對象 //4.獲取結果集 //5.遍歷結果集
} }
解決程序耦合的思路
當是我們講解jdbc時,是通過反射來注冊驅動的,代碼如下:
Class.forName("com.mysql.jdbc.Driver");
這時的好處是,我們的類中不再依賴具體的驅動類,此時就算刪除mysql的驅動jar包,依然可以編譯。但是因為沒有驅動類,所以不能運行。
不過,此處也有個問題,就是我們反射類對象的全限定類名字符串是在java類中寫死的,一旦要改還是要修改源碼。
解決這個問題也很簡單,使用配置文件配置。
工廠模式解耦
在實際開發中我們可以把所有的dao和service和action對象使用配置文件配置起來,當啟動服務器應用加載的時候,通過讀取配置文件,把這些對象創建出來並存起來。在接下來的使用的時候,直接拿過來用就好了。
控制反轉-Inversion Of Control
上面解耦的思路有2個問題:
1、存哪去?
分析:由於我們是很多對象,肯定要找個集合來存。這時候有Map和List供選擇。 到底選Map還是List就看我們有沒有查找需求。有查找需求,選Map。
所以我們的答案就是:
在應用加載時,創建一個Map,用於存放action,Service和dao對象。
我們把這個map稱之為容器。
2、還是沒解釋什么是工廠?
工廠就是負責給我們從容器中獲取指定對象的類。這時候我們獲取對象的方式發生了改變。
原來:
我們在獲取對象時,都是采用new的方式。是主動的。
現在:
我們獲取對象時,同時跟工廠要,有工廠為我們查找或者創建對象。是被動的。
這種被動接收的方式獲取對象的思想就是控制反轉,它是spring框架的核心之一。
它的作用只有一個:削減計算機程序的耦合。
學習了上面的控制反轉,我們得出了一個結論:Spring是利用工廠模式的形式完成了解耦!使我們從原來的主動調用者,變為了被動的獲取者的轉變。(一些面試時常問這個問題)
Spring的依賴注入
依賴注入的概念
它是spring框架核心ioc的具體實現方式。簡單的說,就是坐等框架把對象傳入,而不用我們自己去獲取。從此,當我們需要用到一個對象時,只需從從spring容器中獲取即可(前提是你事先把那個對象交給了spring容器管理,即在xml中事先配置)
依賴注入的兩種方式:構造函數注入和set方法注入
1 構造函數注入
顧名思義,就是使用類中的構造函數,給成員變量賦值。注意,賦值的操作不是我們自己做的,而是通過配置的方式,讓spring框架來為我們注入
2 set方法注入
顧名思義,就是在類中提供需要注入成員的set方法。
Spring的切面編程--AOP
什么是AOP?
AOP:全稱是Aspect Oriented Programming即:面向切面編程。
AOP的作用及優勢
作用:
在程序運行期間,不修改源碼對已有方法進行增強。
優勢:
減少重復代碼 提高開發效率 維護方便
AOP的實現方式
使用動態代理技術
說道切面編程,也許有很多人會很困惑,編程可以理解,而什么是切面呢?下面我們來詳細的慢慢解釋一下:
首先,我們可以設想一下,在我們原先的項目中service層的一些需要事物控制的方法內,是不是一個方法內就需要寫一段事物控制代碼?這就導致了一個問題:
我們的事務控制是重復性的代碼。
為什么這么說呢?因為一個類中就需要些多個事物控制代碼了,那么如果有多個業務了,每個業務類中就都會有這些重復的代碼。因此我們得出了這個結論。
思考:
我們怎么解決呢?:動態代理
動態代理回顧:
動態代理的特點:
字節碼隨用隨創建,隨用隨加載。它與靜態代理的區別也在於此。因為靜態代理是字節碼一上來就創建好,並完成加載。裝飾者模式就是靜態代理的一種體現。
動態代理常用的兩種方式:
基於接口的動態代理:
提供者:JDK官方的Proxy類。
要求:被代理類最少實現的一個接口。
基於子類的動態代理:
提供者:第三方的CGLib,如果報asmxxxx異常,需要導入asm.jar。
要求:被代理類不能用final修飾的類(最終類)。
Spring中的AOP
關於代理的選擇:
在spring中,框架會根據目標類是否實現了接口來決定采用哪種動態代理的方式。
AOP相關術語:
Joinpoint(連接點):
所謂連接點是指那些被攔截到的點。在spring中,這些點指的是方法,因為spring只支持方法類型的連接點。
Pointcut(切入點):
所謂切入點是指我們要對哪些Joinpoint進行攔截的定義。
Advice(通知/增強):
所謂通知是指攔截到Joinpoint之后所要做的事情就是通知。
通知的類型:前置通知,后置通知,異常通知,最終通知,環繞通知。
Introduction(引介):
引介是一種特殊的通知在不修改類代碼的前提下, Introduction可以在運行期為類動態地添加一些方法或Field。
Target(目標對象):
代理的目標對象。
Weaving(織入):
是指把增強應用到目標對象來創建新的代理對象的過程。
spring采用動態代理織入,而AspectJ采用編譯期織入和類裝載期織入。
Proxy(代理):
一個類被AOP織入增強后,就產生一個結果代理類。
Aspect(切面):
是切入點和通知(引介)的結合。
學習spring中的AOP要明確的事
a、開發階段(我們做的)
編寫核心業務代碼(開發主線):大部分程序員來做,要求熟悉業務需求。
把公用代碼抽取出來,制作成通知。(開發階段最后再做):AOP編程人員來做。
在配置文件中,聲明切入點與通知間的關系,即切面。:AOP編程人員來做。
b、運行階段(Spring框架完成的)
Spring框架監控切入點方法的執行。一旦監控到切入點方法被運行,使用代理機制,動態創建目標對象的代理對象,根據通知類別,在代理對象的對應位置,將通知對應的功能織入,完成完整的代碼邏輯運行。
總結:
面向切面編程(AOP),在面向對象編程(oop)思想中,我們將事物縱向抽成一個個的對象。而在面向切面編程中,我們將一個個的對象某些類似的方面橫向抽成一個切面,對這個切面進行一些如權限控制、事物管理,記錄日志等公用操作處理的過程就是面向切面編程的思想。
編后語:Spring框架的內容太多了,本人目前也在學習中,以上內容僅是我根據自己目前掌握的內容以及一些借鑒資料編寫,不足以確保一點不差,所以如有不對的地方,歡迎各位朋友指正,希望我們能共同進步。