日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Spring实战1:Spring初探

發(fā)布時(shí)間:2025/3/21 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring实战1:Spring初探 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

現(xiàn)在的Java程序員趕上了好時(shí)候。在將近20年的歷史中,Java的發(fā)展歷經(jīng)沉浮。盡管有很多為人詬病的產(chǎn)品,例如applets、EJB、Java Data Object(JDO)和數(shù)不清的日志框架,Java還是發(fā)展為一個(gè)龐大且豐富的開(kāi)發(fā)平臺(tái),很多企業(yè)級(jí)應(yīng)用都是基于JVM平臺(tái)構(gòu)建。Spring是JVM開(kāi)發(fā)平臺(tái)中的一顆明珠。

Spring最開(kāi)始出現(xiàn)的目的是替代企業(yè)級(jí)開(kāi)發(fā)框架EJB,相比EJB,Spring提供更輕量和更易用的編程模型。Spring的重要特點(diǎn)是非侵入式增強(qiáng)POJO(plain old java object)的能力。

在后續(xù)的發(fā)展過(guò)程中,EJB也效仿Spring的做法提供了簡(jiǎn)單的以POJO為中心的編程模型,現(xiàn)在的EJB框架也擁有依賴注入(DI)和面向切面編程(AOP)能力,可以論證是受Spring成功的影響。

盡管J2EE一直在追趕Spring的發(fā)展,但是Spring本身也沒(méi)有停止進(jìn)步。現(xiàn)在,Spring在一些J2EE剛剛涉入或者完全沒(méi)有涉入的領(lǐng)域飛速發(fā)展:移動(dòng)開(kāi)發(fā)、社交API整合、NoSQL數(shù)據(jù)庫(kù)、云計(jì)算和大數(shù)據(jù)。就目前來(lái)看,Spring的未來(lái)一片光明。

重要的事情再?gòu)?qiáng)調(diào)一遍:現(xiàn)在的Java程序員趕上了好時(shí)候。

這篇文章會(huì)從一個(gè)比較高的層次探索Spring,介紹Spring框架解決了哪些主要問(wèn)題。

1.1 簡(jiǎn)化Java開(kāi)發(fā)

Spring是一種開(kāi)源框架,由Rod Johnson發(fā)明,并在其著作《Expert One-on-One:J2EE設(shè)計(jì)與開(kāi)發(fā)》。Spring的初衷是降低企業(yè)級(jí)開(kāi)發(fā)的復(fù)雜性,并試圖通過(guò)POJO對(duì)象實(shí)現(xiàn)之前EJB這類重型框架才能實(shí)現(xiàn)的功能。Spring不僅僅對(duì)服務(wù)端開(kāi)發(fā)有用,任何Java應(yīng)用都可受益于Spring的簡(jiǎn)潔、易測(cè)試和低耦合等特性。

Spring框架中使用beans或JavaBeans來(lái)表示應(yīng)用程序中的組件,但這并不意味著該組件必須嚴(yán)格滿足Java Bean的規(guī)范。

Spring做了很多事情,但是歸根到底是一些基本的思路,而所有這些思路最終都導(dǎo)向Spring的使命:簡(jiǎn)化Java開(kāi)發(fā)

Spring通過(guò)下列四種策略來(lái)簡(jiǎn)化Java開(kāi)發(fā):

  • 基于POJO的輕量級(jí)、最小侵入式開(kāi)發(fā);
  • 通過(guò)依賴注入和面向接口編程實(shí)現(xiàn)松耦合;
  • 通過(guò)面向切面編程和慣例實(shí)現(xiàn)聲明式編程;
  • 通過(guò)面向切面編程和模板消除樣板式代碼(boierplate code)

幾乎Spring的每條特性都可以追溯到這四條策略之一,接下來(lái)分別對(duì)這四條策略進(jìn)行闡述,并給出具體的代碼說(shuō)明Spring如何簡(jiǎn)化Java開(kāi)發(fā)。

1.1.1 激發(fā)POJO的能力

如果你做Java開(kāi)發(fā)足夠久,你應(yīng)該遇到過(guò)很多會(huì)束縛程序員能力的開(kāi)發(fā)框架,這些框架要求程序員繼承框架提供的類或者實(shí)現(xiàn)它提供的接口,例如EJB框架中的session beans,另外,在EJB之前的很多框架中也有類似的侵入式編程模型,如Struts、WebWork、Tapestry等等。

Spring盡量避免讓自己的API污染你的應(yīng)用代碼。Spring幾乎不會(huì)強(qiáng)制要求開(kāi)發(fā)人員實(shí)現(xiàn)某個(gè)Spring提供的接口或者繼承某個(gè)Spring提供的類,在Spring應(yīng)用中的Java類看起來(lái)和普通類一樣,不過(guò),Spring現(xiàn)在經(jīng)常使用注解來(lái)修飾Java類,但是這個(gè)類還是一個(gè)POJO。

舉個(gè)代碼例子說(shuō)明,看如下的HelloWorldBean

package com.spring.sample; public class HelloWorldBean {public String sayHello() {return "Hello World";} }

可以看出,這就是一個(gè)簡(jiǎn)單的Java類-POJO,沒(méi)有什么特殊的標(biāo)志表明它是一個(gè)Spring組件。Spring這種非侵入式編程模型使得這個(gè)類在Spring和非Spring框架下具備相同的功能。

盡管形式非常簡(jiǎn)單,POJO的能力值卻可能非常高,例如Spring可以通過(guò)依賴注入編織這些POJOs來(lái)激發(fā)POJO的能力。

1.1.2 依賴注入

依賴注入聽(tīng)起來(lái)比較嚇人,貌似一種非常復(fù)雜的編程技術(shù)或者設(shè)計(jì)模式。實(shí)際上依賴注入并不復(fù)雜,通過(guò)在工程中應(yīng)用依賴注入技術(shù),可以得到更簡(jiǎn)單、更容易理解和測(cè)試的代碼。

How DI works

除了Hello-world級(jí)別的程序,稍微復(fù)雜一點(diǎn)的Java應(yīng)用都需要多個(gè)類配合實(shí)現(xiàn)功能。一般而言,每個(gè)類自己負(fù)責(zé)獲取它要合作的類對(duì)象的引用,這會(huì)導(dǎo)致代碼高度耦合且難以測(cè)試。

首先看如下代碼:

package com.spring.sample.knights; public class DamselRescuingKnight implements Knight {private RescueDamselQuest quest;public DamselRescuingKnight() {this.quest = new RescueDamselQuest(); //與RescueDamselQuest緊耦合}public void embarkOnQuest() {quest.emark();} }

可以看出,DamselRescuingKnight在它的構(gòu)造函數(shù)中創(chuàng)建了自己的Quest實(shí)例——RescueDamselQuest實(shí)例,這使得DamselRescuingKnight與RescueDamselQuest緊密耦合,如果需要刺殺Damsel,則這個(gè)刀可以使用,但是如果需要刺殺恐龍,則這個(gè)刀就派不上用場(chǎng)了。

更糟的是,給DamselRescuingKnight寫單元測(cè)試很不方便,在這個(gè)測(cè)試中,你必須確認(rèn):當(dāng)調(diào)用knight的emarkOnQuest函數(shù)時(shí),quest的embark函數(shù)也正確調(diào)用,但這并不容易。

耦合是一頭雙頭怪:一方面,緊耦合的代碼難以測(cè)試、難以復(fù)用并且難以理解,并且經(jīng)常陷入“修復(fù)一個(gè)bug但引入一個(gè)新的bug”的開(kāi)發(fā)怪圈中;另一方面,應(yīng)用程序必須存在適當(dāng)?shù)鸟詈?#xff0c;否則該應(yīng)用無(wú)法完成任何功能。總之,耦合是必要的,但是應(yīng)該控制組件之間的耦合程度。

通過(guò)使用依賴注入(DI)技術(shù),對(duì)象之間的依賴關(guān)系由Spring框架提供的容器進(jìn)行管理,而不需要某個(gè)對(duì)象主動(dòng)創(chuàng)建自己需要的引用,如下圖所示:

依賴注入的作用

再看一個(gè)BraveKnight類的例子:

package com.spring.sample.knights;public class BraveKnight implements Knight {private Quest quest;public BraveKnight(Quest quest) { // Quest實(shí)例被注入this.quest = quest;}public void embarkOnQuest() {quest.emark();} }

該對(duì)象不再局限于一種quest實(shí)例,在構(gòu)造過(guò)程中利用構(gòu)造函數(shù)的參數(shù)傳入quest實(shí)例,這種類型的依賴注入稱為構(gòu)造注入。

還有一點(diǎn)需要注意,使用接口定義quest實(shí)例,這就是面向接口編程,使得BraveKnight不再局限于某種特定的Quest實(shí)現(xiàn),這就是DI帶來(lái)的最大的好處——松耦合。

實(shí)現(xiàn)依賴注入

在上述例子代碼可以看出,Spring相當(dāng)于將依賴注入的位置從BraveKnight類中剝離出來(lái),那么具體的依賴注入代碼如何寫呢?開(kāi)發(fā)人員如何規(guī)定給BraveKnight注入哪個(gè)Quest實(shí)現(xiàn),例如SlayDragonQuest?

package com.spring.sample.knights;import java.io.PrintStream;public class SlayDragonQuest implements Quest {private PrintStream stream;public SlayDragonQuest(PrintStream stream) {this.stream = stream;}public void emark() {stream.println("Embarking on quest to slay the dragon!");} }

在Spirng框架中,最通用的方法是通過(guò)寫XML配置文件來(lái)定義組件之間的依賴關(guān)系,如下所示:

<?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 id="knight" class="com.spring.sample.knights.BraveKnight"><constructor-arg ref="quest" /></bean><bean id="quest" class="com.spring.sample.knights.SlayDragonQuest"><constructor-arg value="#{T(System).out}" /></bean> </beans>

在這個(gè)xml配置文件中分別定義了BraveKnight和SlayDragonQuest兩個(gè)bean:在BraveKnightbean的定義中,通過(guò)構(gòu)造器函數(shù)傳入一個(gè)SlayDragonQuest的引用;在SlayDragonQuest的定義中,通過(guò)SpEL語(yǔ)言將System.out傳入它的構(gòu)造函數(shù)。

Spring 3.0引入了JavaConfig,這種寫法比xml文件的好處是具備類型安全檢查,例如,上面XML配置文件可以這么寫:

package com.spring.sample.knights.config;import com.spring.sample.knights.BraveKnight; import com.spring.sample.knights.Knight; import com.spring.sample.knights.Quest; import com.spring.sample.knights.SlayDragonQuest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class KnightConfig {@Beanpublic Knight knight() {return new BraveKnight(quest());}@Beanpublic Quest quest() {return new SlayDragonQuest(System.out);} }

不論是基于XML的配置還是基于Java文件的配置,都由Spring框架負(fù)責(zé)管理beans之間的依賴關(guān)系。

啟動(dòng)依賴注入

在Spring應(yīng)用中,由application context負(fù)責(zé)加載beans,并將這些beans根據(jù)配置文件編織在一起。Spring框架提供了幾種application context的實(shí)現(xiàn),如果使用XML格式的配置文件,則使用ClassPathXmlApplicationContext;如果使用Java文件形式的配置文件,則使用AnnotationConfigApplicationContext。

package com.spring.sample.knights;import com.spring.sample.knights.config.KnightConfig; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class KnightMain {public static void main(String[] args) { // ClassPathXmlApplicationContext context = // new ClassPathXmlApplicationContext("classpath:/knight.xml");AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(KnightConfig.class);Knight knight = context.getBean(Knight.class);knight.embarkOnQuest();context.close();} }

上述代碼中,根據(jù)KnightConfig.java文件創(chuàng)建Spring應(yīng)用上下文,可以把該應(yīng)用上下文看成對(duì)象工廠,來(lái)獲取idknight的bean。

如果你想了解更多關(guān)于DI的知識(shí),可以查看Dhanji R. Prasanna's Dependency Injectionhttps://www.manning.com/books/dependency-injection一書。

1.1.3 切面編程

依賴注入(DI)實(shí)現(xiàn)了模塊之間的松耦合,而利用面向切面編程(AOP)可以將涉及整個(gè)應(yīng)用的基礎(chǔ)功能(安全、日志)放在一個(gè)可復(fù)用的模塊中。

AOP是一種在軟件系統(tǒng)中實(shí)現(xiàn)關(guān)注點(diǎn)分離的技術(shù)。軟件系統(tǒng)由幾個(gè)模塊構(gòu)成,每個(gè)模塊負(fù)責(zé)一種功能,不過(guò)在系統(tǒng)中有些需求需要涉及到所有的模塊,例如日志、事務(wù)管理和安全等。如果將這些需求相關(guān)的代碼都分散在各個(gè)模塊中,一方面是不方便維護(hù)、另一方面是與原來(lái)每個(gè)模塊的業(yè)務(wù)邏輯代碼混淆在一起,不符合單一職責(zé)原則。

  • 實(shí)現(xiàn)系統(tǒng)級(jí)別處理的代碼分散在多個(gè)子模塊中,這意味著如果要修改這些處理代碼,則要在每個(gè)模塊中都進(jìn)行修改。即使將這些代碼封裝到一個(gè)模塊中,在沒(méi)給個(gè)子模塊中只保留對(duì)方法的調(diào)用,這些方法調(diào)用還是在各個(gè)模塊中重復(fù)出現(xiàn)。
  • 業(yè)務(wù)邏輯代碼與非核心功能的代碼混淆在一起。例如,一個(gè)添加address book的方法應(yīng)該只關(guān)心如何添加address book,而不應(yīng)該關(guān)心該操作是否安全或者是否能夠?qū)崿F(xiàn)事務(wù)處理。

下面這張圖可以體現(xiàn)這種復(fù)雜性,左邊的業(yè)務(wù)邏輯模塊與右邊的系統(tǒng)服務(wù)模塊溝通太過(guò)密切,每個(gè)業(yè)務(wù)模塊需要自己負(fù)責(zé)調(diào)用這些系統(tǒng)服務(wù)模塊。

業(yè)務(wù)邏輯模塊與系統(tǒng)服務(wù)模塊過(guò)度交互

AOP可以模塊化這些系統(tǒng)服務(wù),然后利用聲明式編程定義該模塊需要應(yīng)用到那些業(yè)務(wù)邏輯模塊上。這使得業(yè)務(wù)模塊更簡(jiǎn)潔,更專注于處理業(yè)務(wù)邏輯,簡(jiǎn)而言之,切面(aspects)確保POJO仍然是普通的Java類。

可以將切面想象為覆蓋在一些業(yè)務(wù)模塊上的毯子,如下圖所示。在系統(tǒng)中有一些模塊負(fù)責(zé)核心的業(yè)務(wù)邏輯,利用AOP可以為所有這些模塊增加額外的功能,而且核心業(yè)務(wù)模塊無(wú)需知道切面模塊的存在。

切面就像毯子一樣覆蓋在幾個(gè)核心業(yè)務(wù)模塊之上

AOP實(shí)踐

繼續(xù)上面的例子,如果需要一個(gè)人記錄BraveKnight的所作所為,下面代碼是該日志服務(wù):

package com.spring.sample.knights;import java.io.PrintStream;public class Minstrel {private PrintStream stream;public Minstrel(PrintStream stream) {this.stream = stream;}public void singBeforeQuest() {stream.println("Fa la la, the knight is so brave!");}public void singAfterQuest() {stream.println("Tee hee hee, the brave knight did embark on a quest!");} }

然后在XML文件中定義Minstrel對(duì)應(yīng)的切面:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="knight" class="com.spring.sample.knights.BraveKnight"><constructor-arg ref="quest" /></bean><bean id="quest" class="com.spring.sample.knights.SlayDragonQuest"><constructor-arg value="#{T(System).out}" /></bean><bean id="minstrel" class="com.spring.sample.knights.Minstrel"><constructor-arg value="#{T(System).out}" /></bean><aop:config><aop:aspect ref="minstrel"><aop:pointcut id="embark" expression="execution(* *.embarkOnQuest(..))"/><aop:before method="singBeforeQuest" pointcut-ref="embark" /><aop:after method="singAfterQuest" pointcut-ref="embark" /></aop:aspect></aop:config> </beans>

在這個(gè)配置文件中增加了aop配置名字空間。首先定義Minstrel的bean,然后利用<aop:config>標(biāo)簽定義aop相關(guān)的配置;然后在<aop:aspect>節(jié)點(diǎn)中引用minstrel,定義方面;aspect負(fù)責(zé)將pointcut和要執(zhí)行的函數(shù)(before、after或者around)連接在一起。

還有一種更先進(jìn)的寫法,利用注解和Java配置文件,可以參考aop docs

Spring框架中的一些子模塊也是基于AOP實(shí)現(xiàn)的,例如負(fù)責(zé)事務(wù)處理和負(fù)責(zé)安全的模塊。

1.1.4 使用模板消除重復(fù)代碼

在編程過(guò)程中有沒(méi)有感覺(jué)經(jīng)常需要寫重復(fù)無(wú)用的代碼才能實(shí)現(xiàn)簡(jiǎn)單的功能,最經(jīng)典的例子是JDBC的使用,這些代碼就是樣板式代碼(boilerplate code)。

以JDBC的使用舉個(gè)例子,這種原始的寫法你一定見(jiàn)過(guò):

public Employee getEmployeeById(long id) {Connection conn = null;PreparedStatement stmt = null;ResultSet rs = null;try {conn = dataSource.getConnection();stmt = conn.prepareStatement("select id, name from employee where id=?");stmt.setLong(1, id);rs = stmt.executeQuery();Employee employee = null;if (rs.next()) {employee = new Employee();employee.setId(rs.getLong("id"));employee.setName(rs.getString("name"));}return employee;} catch (SQLException e) {} finally {if (rs != null) {try {rs.close();} catch (SQLException e) {}} if (stmt != null) {try {stmt.close();} catch (SQLException e) {}}if (conn != null) {try {conn.close();} catch (SQLException e) {}}}return null; }

可以看到,上面這么一坨代碼中只有少數(shù)是真正用于查詢數(shù)據(jù)(業(yè)務(wù)邏輯)的。除了JDBC的接口,其他JMS、JNDI以及REST服務(wù)的客戶端API等也有類似的情況出現(xiàn)。

Spring試圖通過(guò)模板來(lái)消除重復(fù)代碼,這里所用的是模板設(shè)計(jì)模式。對(duì)于JDBC接口,Spring提供了JdbcTemplate模板來(lái)消除上面那個(gè)代碼片段中的樣板式代碼,例子代碼如下:

public Employee getEmployeeById(long id) {return jdbcTemplate.queryForObject("select id, name from employee where id=?",new RowMapper<Employee>() {public Employee mapRow(ResultSet resultSet, int i) throws SQLException {Employee employee = new Employee();employee.setId(resultSet.getLong("id"));employee.setName(resultSet.getString("name"));return employee;}}); }

你沒(méi)有看錯(cuò),就是利用回調(diào)函數(shù)實(shí)現(xiàn)的,有興趣的讀者可以深入研究下JdbcTemplate的源碼實(shí)現(xiàn)。

我們上面已經(jīng)演示了Spring簡(jiǎn)化Java開(kāi)發(fā)的四種策略:面向POJO開(kāi)發(fā)、依賴注入(DI)、面向切面編程和模板工具。在舉例的過(guò)程中,我們稍微提到一點(diǎn)如何使用XML配置文件定義bean和AOP相關(guān)的對(duì)象,但是這些配置文件的加載原理是怎樣的?這就需要研究下Spring的容器,Spring中所定義的bean都由Spring容器管理。

1.2 使用容器管理beans

基于Spring框架構(gòu)建的應(yīng)用中的對(duì)象,都由Spring容器(container)管理,如下圖所示。Spring容器負(fù)責(zé)創(chuàng)建對(duì)象、編織對(duì)象和配置對(duì)象,負(fù)責(zé)對(duì)象的整個(gè)生命周期。

Spring容器的作用

容器是Spring框架的核心,通過(guò)依賴注入(DI)管理構(gòu)成Spring應(yīng)用的組件。正是因?yàn)橛腥萜鞴芾砀鱾€(gè)組件之間的協(xié)作關(guān)系,使得每個(gè)Spring組件都很好理解、便于復(fù)用和單元測(cè)試。

Spring容器有多種實(shí)現(xiàn),可以分為兩類:

  • Bean factories(由org.springframework.beans.factory.BeanFactory接口定義)是最簡(jiǎn)單的容器,只提供基本的依賴注入功能;
  • Application context(由org.springframework.context.ApplicationContext接口定義)在bean factory的基礎(chǔ)上提供application-framework框架服務(wù),例如可以從properties文件中解析配置信息、可以對(duì)外公布application events。

1.2.1 應(yīng)用上下文(application context)

Spring提供了多種application context,可列舉如下:

  • AnnotationConfigApplicationContext——從Java配置文件中加載應(yīng)用上下文;
  • AnnotationConfigWebApplicationContext——從Java配置文件中加載Spring web應(yīng)用上下文;
  • ClassPathXmlApplicationContext——從classpath(resources目錄)下加載XML格式的應(yīng)用上下文定義文件;
  • FileSystemXmlApplicationContext——從指定文件系統(tǒng)目錄下加載XML格式的應(yīng)用上下文定義文件;
  • XmlWebApplicationContext——從classpath(resources目錄)下加載XML格式的Spring web應(yīng)用上下文。

通過(guò)應(yīng)用上下文實(shí)例,可以通過(guò)getBean()方法獲得對(duì)應(yīng)的bean。

1.2.2 bean的生命周期

在傳統(tǒng)的Java應(yīng)用中,一個(gè)對(duì)象的生命周期非常簡(jiǎn)單:通過(guò)new創(chuàng)建一個(gè)對(duì)象,然后該對(duì)象就可以使用,當(dāng)這個(gè)對(duì)象不再使用時(shí),由Java垃圾回收機(jī)制進(jìn)行處理和回收。

在Spring應(yīng)用中,bean的生命周期的控制更加精細(xì)。Spring提供了很多節(jié)點(diǎn)供開(kāi)發(fā)人員定制某個(gè)bean的創(chuàng)建過(guò)程,掌握這些節(jié)點(diǎn)如何使用非常重要。Spring中bean的生命周期如下圖所示:

bean的生命周期

可以看出,bean factory負(fù)責(zé)bean創(chuàng)建的最初四步,然后移交給應(yīng)用上下文做后續(xù)創(chuàng)建過(guò)程:

  • Spring初始化bean
  • Spring將值和其他bean的引用注入(inject)到當(dāng)前bean的對(duì)應(yīng)屬性中;
  • 如果Bean實(shí)現(xiàn)了BeanNameAware接口,Spring會(huì)傳入bean的ID來(lái)調(diào)用setBeanName方法;
  • 如果Bean實(shí)現(xiàn)了BeanFactoryAware接口,Spring傳入bean factory的引用來(lái)調(diào)用setBeanFactory方法;
  • 如果Bean實(shí)現(xiàn)了ApplicationContextAware接口,Spring將傳入應(yīng)用上下文的引用來(lái)調(diào)用setApplicationContext方法;
  • 如果Bean實(shí)現(xiàn)了BeanPostProcessor接口,則Spring調(diào)用postProcessBeforeInitialization方法,這個(gè)方法在初始化和屬性注入之后調(diào)用,在任何初始化代碼之前調(diào)用;
  • 如果Bean實(shí)現(xiàn)了InitializingBean接口,則需要調(diào)用該接口的afterPropertiesSet方法;如果在bean定義的時(shí)候設(shè)置了init-method屬性,則需要調(diào)用該屬性指定的初始化方法;
  • 如果Bean實(shí)現(xiàn)了BeanPostProcessor接口,則Spring調(diào)用postProcessAfterInitialization方法
  • 在這個(gè)時(shí)候bean就可以用于在應(yīng)用上下文中使用了,當(dāng)上下文退出時(shí)bean也會(huì)被銷毀;
  • 如果Bean實(shí)現(xiàn)了DisposableBean接口,Spring會(huì)調(diào)用destroy()方法;如果在bean定義的時(shí)候設(shè)置了destroy-method, 則此時(shí)需要調(diào)用指定的方法。
  • 本節(jié)主要總結(jié)了如何啟動(dòng)Spring容器,以及Spring應(yīng)用中bean的生命周期。

    1.3 Spring整體架構(gòu)

    除了Spring的核心模塊,Spring還提供了其他的工具組件,這些組件擴(kuò)展了Spring的功能,例如webservice、REST、mobile和NOSQL,形成了豐富的開(kāi)發(fā)生態(tài)。

    1.3.1 Spring模塊

    Spring 4.0you 20個(gè)獨(dú)立的模塊,每個(gè)包含三個(gè)文件:二進(jìn)制庫(kù)、源文件和文檔,完整的庫(kù)列表如下圖所示:

    Spring 4.0包含20個(gè)模塊

    按照功能劃分,這些模塊可以分成六組,如下圖所示:

    Spring框架的六組模塊

    這些模塊幾乎可以滿足所有企業(yè)級(jí)應(yīng)用開(kāi)發(fā)的需求,但是開(kāi)發(fā)人員并不需要完全使用Spring的這些模塊,可以自由選擇符合項(xiàng)目需求的第三方模塊——Spring為一些第三方模塊提供了交互接口。

    CORE SPRING CONTAINER

    Spring框架的核心模塊,其他所有模塊都基于該模塊構(gòu)建。Spring容器負(fù)責(zé)管理Spring應(yīng)用中bean的創(chuàng)建、配置和管理。在這模塊中有Spring bean factory,該接口提供了最基本的依賴注入(DI)功能;基于bean factory,該模塊提供了集中Spring應(yīng)用上下文的實(shí)現(xiàn),可以供開(kāi)發(fā)人員選擇。

    除了bean factory和application context,該模塊還支持其他企業(yè)級(jí)服務(wù),例如email、JNDI access、EJB integration和scheduling。

    SPRING's AOP MODULE

    Spring框架通過(guò)AOP模塊提供面向切面編程的能力。通過(guò)AOP模塊,一些系統(tǒng)層面的需求(事務(wù)、安全)可以與它們真正要作用到的模塊相互解耦合。

    DATA ACCESS AND INTEGRATION

    Spring的JDBC和data-access object模塊將數(shù)據(jù)庫(kù)操作的一些樣板式代碼封裝起來(lái),免去了開(kāi)發(fā)人員的很多工作量。這個(gè)模塊還對(duì)數(shù)據(jù)庫(kù)層的異常進(jìn)行了封裝,并向上提供含義更豐富的異常信息。

    Spring并未實(shí)現(xiàn)自己的ORM框架,但是它提供了跟其他幾個(gè)ORM框架整合的能力,例如Hibernate、Mybatis、Java Persistence AP等等,而且這些ORM框架都支持使用Spring提供的事務(wù)管理模塊。

    WEB AND REMOTING

    Spring提供了自己的 WEB開(kāi)發(fā)框架——Spring MVC,除此之外,這個(gè)模塊還提供遠(yuǎn)程調(diào)用支持:Remote Method Invocation(RMI)、Hessian、Burlap和JAX-WS。

    INSTRUMENTATION

    不常使用

    TESTING

    可以與常用的JUNIT、Mockito、Spock等測(cè)試框架整合使用。

    1.3.2 Spring portfolio

    如果只是學(xué)習(xí)Spring的核心模塊,將會(huì)錯(cuò)過(guò)不少Spring社區(qū)提供的經(jīng)典項(xiàng)目,下面介紹的這些項(xiàng)目使得Spring幾乎可以覆蓋整個(gè)Java開(kāi)發(fā)(PS:帶*的項(xiàng)目值得每位Spring用戶仔細(xì)學(xué)習(xí))。

    SPRING WEB FLOW

    基于Spring MVC框架拓展,利用該框架可以構(gòu)建流式web應(yīng)用。

    SPRING WEB SERVICE

    雖然核心的Spring 框架提供了將Spring Bean 以聲明的方式發(fā)布為Web Service,但是這些服務(wù)基于一個(gè)具有爭(zhēng)議性的架構(gòu)(拙劣的契約置后模型)之上而構(gòu)建的。這些服務(wù)的契約由Bean 的接口來(lái)決定。 Spring Web Service 提供了契約優(yōu)先的Web Service模型,服務(wù)的實(shí)現(xiàn)都是為了滿足服務(wù)的契約而編寫的。

    SPRING SECURITY(*)

    安全對(duì)于許多應(yīng)用都是一個(gè)非常關(guān)鍵的切面。利用Spring AOP,Spring Security為Spring 應(yīng)用提供了聲明式的安全機(jī)制。我們將在第9 章講解如何為應(yīng)用添加SpringSecurity。你可以在主頁(yè)http://static.springsource.org/spring-security/site?獲得關(guān)于SpringSecurity 更多的信息。

    SPRING INTEGRATION

    許多企業(yè)級(jí)應(yīng)用都需要與其他應(yīng)用進(jìn)行交互。Spring Integration 提供了幾種通用的應(yīng)用集成模式的Spring 聲明式風(fēng)格的實(shí)現(xiàn)。

    我們不會(huì)在本書覆蓋Spring Integration 內(nèi)容,但是如果你想了解更多關(guān)于SpringIntegration 的信息, 我推薦Mark Fisher、Jonas Partner、Marius Bogoevici 和IweinFuld 編寫的《Spring Integration in Action》;或者還可以訪問(wèn)Spring Integration 的主頁(yè)http://www.springsource.org/spring-integration。

    SPRING BATCH

    當(dāng)我們需要對(duì)數(shù)據(jù)進(jìn)行大量操作時(shí),沒(méi)有任何技術(shù)可以比批處理更能勝任此場(chǎng)景的。如果需要開(kāi)發(fā)一個(gè)批處理應(yīng)用,你可以借助于Spring 強(qiáng)大的面向POJO 的編程模型來(lái)使用Spring Batch 來(lái)實(shí)現(xiàn)。

    Spring Batch 超出了本書的范疇,但是你可以閱讀Thierry Templier 和Arnaud Cogoluègnes編寫的《Spring Batch in Action》,或者訪問(wèn)Spring Batch 的主頁(yè)http://static.springsource.org/spring-batch。

    SPRING DATA(*)

    Spring Data用于簡(jiǎn)化數(shù)據(jù)庫(kù)相關(guān)的開(kāi)發(fā)工作。盡管多年以來(lái)關(guān)系型數(shù)據(jù)庫(kù)都是企業(yè)級(jí)應(yīng)用開(kāi)發(fā)的主流,但是隨著移動(dòng)互聯(lián)網(wǎng)的發(fā)展,對(duì)NoSQL這類菲關(guān)系型數(shù)據(jù)庫(kù)的需求也越來(lái)越強(qiáng)。

    無(wú)論你選擇NoSQL還是關(guān)系型數(shù)據(jù)庫(kù),Spring Datat都能提供簡(jiǎn)潔的編程模型,例如非常方便的repository機(jī)制,可以為開(kāi)發(fā)人員自動(dòng)創(chuàng)建具體的SQL實(shí)現(xiàn)。

    SPRING SOCIAL

    社交網(wǎng)絡(luò)是互聯(lián)網(wǎng)冉冉升起的一顆新星,越來(lái)越多的應(yīng)用正在融入社交網(wǎng)絡(luò)網(wǎng)站,例如Facebook 或者Twitter。如果對(duì)此感興趣,你可以了解下Spring Social,Spring 的一個(gè)社交網(wǎng)絡(luò)擴(kuò)展模塊。

    Spring Social 相對(duì)還比較新穎,我并沒(méi)有計(jì)劃將它放入本書,但是你可以訪問(wèn)http://www.springsource.org/spring-social?了解Spring Social 更多的相關(guān)信息。

    SPRING MOBILE

    移動(dòng)應(yīng)用是另一個(gè)引人矚目的軟件開(kāi)發(fā)領(lǐng)域。智能手機(jī)和平板設(shè)備已成為許多用戶首選的客戶端。Spring Mobile 是Spring 新的擴(kuò)展模塊用于支持移動(dòng)Web 應(yīng)用開(kāi)發(fā)。
    與Spring Mobile 相關(guān)的是Spring Android 項(xiàng)目。這個(gè)新項(xiàng)目旨在通過(guò)Spring 框架為開(kāi)發(fā)基于Android 設(shè)備的本地應(yīng)用提供某些簡(jiǎn)單的支持。最初,這個(gè)項(xiàng)目提供了Spring 的RestTemplate 版本(請(qǐng)查看第11 章了解RestTemplete)可以用于Android 應(yīng)用。
    再次聲明,這兩個(gè)項(xiàng)目已超出了本書的范圍,但是如果你對(duì)這兩個(gè)項(xiàng)目感興趣,可以訪問(wèn)http://www.springsource.org/spring-mobile?和http://www.springsource.org/spring-android?了解更多相關(guān)的信息。

    SPRING BOOT(*)

    Spring Boot是Spring社區(qū)中發(fā)展速度最快的框架之一,它旨在簡(jiǎn)化Spring的使用,解決Spring開(kāi)發(fā)時(shí)遇到的“配置地獄”問(wèn)題。

    Spring Boot通過(guò)大量使用自動(dòng)配置技術(shù),可以取消大量的XML配置文件,同時(shí)該框架提出了starter的概念,用于簡(jiǎn)化pom文件。可以參考我的一系列博文:《Spring Boot Cookbook》閱讀筆記

    1.4 Spring的新特點(diǎn)(書中總結(jié)和自己的觀點(diǎn))

    主要總結(jié)下Spring社區(qū)的趨勢(shì):

  • 注重注解,能用注解解決的盡量用注解,盡量少寫XML配置文件;
  • Spring Boot已經(jīng)是Spring社區(qū)中增長(zhǎng)最迅速的框架,前三名是:Spring Framework,Spring Boot和Spring Security
  • 支持Java 8,通過(guò)Java8的lambda表達(dá)式,使得一些回調(diào)接口更易使用和閱讀。
  • 與Groovy開(kāi)發(fā)平滑支持,Groovy是JVM上的Python語(yǔ)言,在Spring項(xiàng)目中可以寫單元測(cè)試;
  • 支持JSR-310:Data和Time API,為開(kāi)發(fā)人員提供豐富的接口操作java.util.Date或者java.util.Clendar。
  • 總結(jié)

    以上是生活随笔為你收集整理的Spring实战1:Spring初探的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 久久久久久久久久久91 | 国产中文字幕二区 | 亚洲玖玖爱 | 少妇太紧太爽又黄又硬又爽小说 | 色综合免费视频 | 337p粉嫩大胆色噜噜狠狠图片 | 毛片毛片毛片毛片毛片毛片 | 婷婷网五月天 | 中文日韩字幕 | 久久黄色影视 | 成人综合一区二区 | 国模福利视频 | 性av免费| 亚洲人成色777777老人头 | 久久人体视频 | 日韩精品一二三四 | 亚洲一区二区免费在线观看 | 香蕉网在线 | 麻豆精品国产传媒av | av有声小说一区二区三区 | 91草视频 | 国产乱子轮xxx农村 岛国久久久 | 91se在线 | 亚洲一区欧美日韩 | 金瓶狂野欧美性猛交xxxx | 福利一区在线观看 | 一区二区三区免费播放 | 亚欧美精品| 亚洲破处视频 | 精品久久久精品 | 调教女m荡骚贱淫故事 | 国产91网址 | 国产精品伊人 | 青青视频在线播放 | 老头糟蹋新婚少妇系列小说 | 久久香蕉综合 | 开心激情网五月天 | 国产视频综合 | 欧美激情久久久久 | 欧美888| 色偷偷噜噜噜亚洲男人的天堂 | 日韩αv| 逼逼av网站 | a级全黄 | 桃色综合网 | 黄色网免费看 | 五月婷婷在线观看 | 狠狠干在线观看 | 亚洲国产欧美另类 | 婷婷综合另类小说色区 | 亚洲天堂导航 | 国产乱淫av片 | 欧美成人黄色小视频 | 苍井空张开腿实干12次 | 久久亚洲精少妇毛片午夜无码 | 国产少妇一区二区 | 伊人成人久久 | 鬼眼| 免费在线观看小视频 | 欧美精品一区二 | 久草综合在线 | 日韩 国产 | 精品黑人一区二区三区在线观看 | 男生桶女生肌肌 | 国产一级啪啪 | 脱女学生小内内摸了高潮 | 91免费视频网址 | 欧美性一区二区 | 曰批女人视频在线观看 | 国产初高中真实精品视频 | 日韩欧美极品 | 亚洲精品18 | 中文字幕丰满孑伦无码专区 | 一区二区三区四区中文字幕 | 午夜毛片| 在线观看黄色网 | 国产精品爽| 毛片毛片女人毛片毛片 | 久久久香蕉 | 日韩精品视频网 | 国产精品99久久免费黑人人妻 | 噜噜噜久久,亚洲精品国产品 | 麻豆av在线播放 | 精品一区二区三区欧美 | 欧美日韩网站 | 日韩一区二区高清 | 色综合久久中文字幕无码 | 久久婷婷视频 | 精品人人人人 | 色网址在线 | 香港台湾日本三级大全 | 人人澡人人插 | 日韩黄色在线视频 | 男人天堂tv| 欧美日韩国产麻豆 | 久99| 久久国内精品 | 破处视频在线观看 | www.色呦呦 |