Spring快速入門

一、概述

Spring是J2EE應(yīng)用程序框架,是輕量級的IoC(控制反轉(zhuǎn))和AOP(面向切面)容器框架,主要針對javaBean的生命周期進(jìn)行管理。使用基本的JavaBean代替了傳統(tǒng)的EJB,降低了企業(yè)應(yīng)用開發(fā)的復(fù)雜性。借助依賴注入、AOP應(yīng)用、面向接口編程等特性,降低了業(yè)務(wù)組件之間的耦合度,增強了系統(tǒng)的可擴展性。Spring是非侵入式的,應(yīng)用中的對象不依賴于Spring的特定類。可以整合和兼容其他框架,讓已有的技術(shù)和框架更加易用。

官網(wǎng)地址

二、框架結(jié)構(gòu)

Spring框架是一個分層架構(gòu),由七個模塊組成。Spring的各模塊構(gòu)建在核心容器之上,核心容器定義了創(chuàng)建、配置和管理bean的方式。

  1. Spring Core

    提供了Spring框架的基本功能。核心容器的主要組件是BeanFactory,是工廠模式的實現(xiàn)。BeanFactory使用IoC將應(yīng)用程序的配置和依賴性規(guī)范與實際的應(yīng)用程序代碼分離。

  2. Spring Context

    是一個配置文件,為Spring框架提供上下文信息。Spring上下文包括各種企業(yè)服務(wù),如JNDI、EJB、電子郵件、國際化、校驗和調(diào)度等。

  3. Spring AOP

    通過配置管理特性,該模塊將面向方面的編程功能集成到了Spring框架中。為基于Spring的應(yīng)用程序中的對象提供了事務(wù)管理服務(wù),將聲明性事務(wù)管理集成到應(yīng)用程序中。

  4. Spring DAO

    提供了有意義的異常層次結(jié)構(gòu),可用該結(jié)構(gòu)來管理異常處理和錯誤信息。異常層次結(jié)構(gòu)簡化了錯誤處理,極大地降低了需要編寫的異常代碼量。

  5. Spring ORM

    Spring框架插入了若干ORM框架,從而提供了ORM的對象關(guān)系工具。所有這些框架都遵從Spring的通用事務(wù)和DAO異常層次結(jié)構(gòu)。

  6. Spring Web

    Web上下文模塊建立在應(yīng)用程序上下文模塊之上,為基于Web的應(yīng)用程序提供了上下文。Web模塊還簡化了處理多部分請求以及將請求參數(shù)綁定到域?qū)ο蟮墓ぷ鳌?/p>

  7. Spring MVC

    SpringMVC框架是一個全功能的構(gòu)建Web應(yīng)用程序的MVC實現(xiàn)。

三、核心組件

Spring框架的核心組件主要有三個:Bean組件、Context組件、Core組件。

1、Bean組件

Bean組件在Spring的org.springframework.beans包下,這個包下的所有類主要負(fù)責(zé)bean的定義、創(chuàng)建、以及對bean的解析。在實際使用中只需要關(guān)注bean的創(chuàng)建即可,bean的定義和bean的解析由框架完成。

  • bean的創(chuàng)建使用工廠模式,頂層接口是BeanFactory,最終的實現(xiàn)類是DefaultListableBeanFactory。BeanFactory有三個子接口:ListableBeanFactory、HierarchicalBeanFactory、AutowireCapableBeanFactory。這四個接口共同定義了bean的集合、bean之間的關(guān)系、以及bean的行為。
  • bean的定義主要由BeanDefinition描述,描述了配置文件中所定義的<bean>節(jié)點中的所有信息。當(dāng)Spring成功解析節(jié)點后,節(jié)點信息被轉(zhuǎn)化成BeanDefinition對象,之后所有的操作都是針對該對象。
  • bean的解析主要就是對Spring配置文件的解析。

2、Context組件

Context組件在Spring的org.springframework.context包下,提供一個運行時環(huán)境,用以保存各個對象的狀態(tài)。ApplicationContext是Context的頂級父類,標(biāo)識了一個應(yīng)用環(huán)境的基本信息。還繼承了五個接口,主要擴展Context的功能。

ApplicationContext主要有兩個子類:

  • ConfigurableApplicationContext,表示該Context是可修改的,用戶在構(gòu)建Context時可以動態(tài)添加或修改已有的配置信息。
  • WebApplicationContext,表示是為web準(zhǔn)備的Context,可以直接訪問ServletContext。

ApplicationContext必須完成以下幾件事:

  • 標(biāo)識一個應(yīng)用環(huán)境
  • 利用BeanFactory創(chuàng)建Bean對象
  • 保存對象關(guān)系表
  • 能夠捕獲各種事件

3、Core組件

Core組件包含了很多關(guān)鍵類,其中一個重要部分就是定義了資源的訪問方式。Resource接口封裝了各種可能的資源類型,對使用者屏蔽了文件類型的不同。Resource接口繼承了InputStreamSource接口,接口中的getInputStream方法返回InputStream類,所有的資源都可以通過這個類來獲取,也屏蔽了資源的提供者。ResourceLoader接口屏蔽了資源的加載者,只需要實現(xiàn)這個接口就可以加載所有類型的資源。Context把資源的加載、解析和描述工作委托給ResourcePatternResolver類來完成,由它整合在一起供其他組件使用。

四、原理

1、IoC

IoC是Spring的核心之一。傳統(tǒng)情況下,當(dāng)一個對象依賴于另一個對象時,需要通過new操作主動創(chuàng)建另一個對象的實例,這樣的話,兩個對象之間就產(chǎn)生了耦合。通過IoC,一個對象依賴的其他對象會通過被動的方式傳遞進(jìn)來,而不是自己創(chuàng)建或查找依賴對象。創(chuàng)建依賴對象實例的工作通常由Spring容器來完成,然后注入給依賴者,所以也被稱為DI(依賴注入)。

1.1 IoC容器

BeanFactory是IoC容器的核心接口,負(fù)責(zé)實例化、定位、配置應(yīng)用程序中的對象及建立這些對象間的依賴。XMLBeanFactory實現(xiàn)BeanFactory接口,通過獲取xml配置文件數(shù)據(jù),組成應(yīng)用對象及對象間的依賴關(guān)系。

  • BeanFactoryPostProcessor,在構(gòu)建BeanFactory時調(diào)用
  • BeanPostProcessor,在構(gòu)建Bean對象時調(diào)用
  • InitializingBean,在Bean實例創(chuàng)建時調(diào)用
  • DisposableBean,在Bean實例銷毀時調(diào)用
  • FactoryBean,用來創(chuàng)建Bean實例的Bean

1.2 注入方法

可以通過三種方法進(jìn)行注入:set方法、構(gòu)造函數(shù)、接口。

set方法注入

可以為屬性提供set方法。在配置文件中添加bean標(biāo)簽,屬性class的值為對象實現(xiàn)類的完整路徑。添加property標(biāo)簽,屬性name的值與對象類中對應(yīng)的屬性名稱一致,屬性value的值就是給對象類中對應(yīng)的屬性注入的值。

實現(xiàn)類:

public class User {
    private String username;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username= username;
    }
}

配置文件:

<bean id="userAction" class="com.spring.action.User" >  
    <property name="username" value="admin"></property>  
</bean>  

也可以為對象提供set方法。在配置文件中添加對引用對象的bean聲明,屬性ref的值是所要引用的對象。這樣,框架就會將引用對象注入到對象類中。

實現(xiàn)類:

public class UserAction {
    private UserService userservice;

    public void setUserService(UserService userservice) {
        this.userservice = userservice;
    }
}

配置文件:

<bean id="userService" class="com.spring.service.UserService"></bean>
<bean id="userAction" class="com.spring.action.UserAction" >
    <property name="userservice" ref="userService"></property>
</bean>

構(gòu)造方法注入

直接通過構(gòu)造函數(shù),將要依賴的屬性或?qū)ο笞鳛閰?shù)傳遞給構(gòu)造函數(shù)。

實現(xiàn)類:

public class UserAction {
    private String username;

    public UserAction(String username) {
        this.username= username;
    }
}

配置文件:

<bean id="userAction" class="com.spring.action.UserAction" >
    <constructor-arg constructor-argvalue="admin"></constructor-arg>
</bean>

接口方法注入

并不常用,所以不做介紹。

1.3 自動裝配

修改Spring配置文件中bean標(biāo)簽的autowire屬性,可以進(jìn)行自動裝配,簡化配置,提高開發(fā)效率。自動裝配屬性有六個值,分別代表不同的含義:

  • byName

    從Spring環(huán)境中獲取目標(biāo)對象時,目標(biāo)對象中的屬性會根據(jù)名稱在整個Spring環(huán)境中查找bean標(biāo)簽的id屬性值。如果有相同的,則獲取這個對象,實現(xiàn)關(guān)聯(lián)。要保證id不能重復(fù)。

  • byType

    從Spring環(huán)境中獲取目標(biāo)對象時,目標(biāo)對象中的屬性會根據(jù)名稱在整個Spring環(huán)境中查找bean標(biāo)簽的class屬性值。如果有相同的,則獲取這個對象,實現(xiàn)關(guān)聯(lián)。當(dāng)存在多個相同類型的bean對象時,會出錯。

  • constructor

    使用構(gòu)造方法完成對象注入,也就是根據(jù)構(gòu)造方法的參數(shù)類型進(jìn)行對象查找,相對于采用byType方式。

  • autodetect

    如果對象沒有無參數(shù)的構(gòu)造方法,則自動選擇constructor的裝配方式進(jìn)行構(gòu)造注入;如果對象含有無參數(shù)的構(gòu)造方法,則自動選擇byType的裝配方式進(jìn)行set注入。

  • default

    默認(rèn)采用上一級標(biāo)簽的自動裝配的值。

  • no

    不進(jìn)行自動裝配。

2、AOP

AOP是Spring的另一個核心。Spring通過AOP,允許分離應(yīng)用的業(yè)務(wù)邏輯與系統(tǒng)級服務(wù)(如日志、事務(wù)、權(quán)限等),從而提高了內(nèi)聚性。

2.1 AOP與OOP

AOP即面向切面編程,與OOP面向?qū)ο缶幊滔噍o相成。OOP要求職責(zé)分離,不同的類完成不同的功能,降低了代碼的復(fù)雜度,便于重用。但在職責(zé)分離的同時,如果多個類需要進(jìn)行相同操作時,需要在每個類中都加入這些內(nèi)容,增加了代碼的重復(fù)性。如果將這些內(nèi)容單獨封裝在一個類中,再通過每個類進(jìn)行調(diào)用,會增加類之間的耦合度。AOP就是在程序運行時,動態(tài)地將這些內(nèi)容切入到類的指定方法、指定位置上。OOP中,基本單元是類;AOP中,基本單元是切面。OOP橫向分成各個類,AOP縱向給對象加入特定代碼。

2.2 AOP術(shù)語

AOP中包含很多術(shù)語,理解這些術(shù)語才能全面的理解AOP的真正含義。

  • 切面(Aspect),橫切面的功能,用于抽象出類或接口

    由Advice和Pointcut組成,既包含了橫切面的定義,也包含了切入點的定義。可以使用@Aspect注解實現(xiàn)。

  • 增強(Advice),橫切面功能的具體實現(xiàn),對象的實例

    由Aspect添加到特定Joinpoint的代碼,

  • 連接點(Joinpoint),程序運行期間的時間節(jié)點

    在Spring AOP中,Joinpoint總是表現(xiàn)為方法執(zhí)行。

  • 切入點(Pointcut),描述橫切面功能應(yīng)用的限制

    使用Pointcut的目的就是提供一組規(guī)則來匹配Joinpoint,只為滿足條件的Joinpoint添加Advice代碼。

  • 代理(Proxy),織入Advice的結(jié)果類

    Spring AOP默認(rèn)使用JDK動態(tài)代理為接口實現(xiàn)代理。如果業(yè)務(wù)邏輯對象沒有實現(xiàn)接口,則使用CGLIB代理。Spring AOP建議基于接口編程,對接口進(jìn)行AOP,而不是基于類。

  • 目標(biāo)(Target),業(yè)務(wù)操作的實際對象,織入Advice的目標(biāo)對象,也被稱為被增強的對象

    因為Spring AOP是通過運行時代理的方式實現(xiàn)Aspect的,所以目標(biāo)對象總是一個代理對象。一個類被AOP織入Advice后,會產(chǎn)生一個結(jié)果類,是包含原類和增強邏輯的代理類。

  • 織入(Weave),將組件應(yīng)用到業(yè)務(wù)流程中的過程,將Aspect和其他對象關(guān)聯(lián)并創(chuàng)建目標(biāo)對象的過程

    Spring采用動態(tài)代理織入,而AspectJ則采用編譯器和類裝載器織入。

2.3 用法

定義Aspect

當(dāng)使用注解@Aspect標(biāo)注一個Bean后,Spring框架會自動將其添加到Spring AOP中。要想將對象轉(zhuǎn)換成Bean,還需要使用@Component之類的注解。如果一個類被@Aspect標(biāo)注,那么這個類就不能成為其他Aspect的目標(biāo)對象了。

@Component
@Aspect
public class Test{
}

聲明Pointcut

Pointcut聲明由兩部分組成:一個pointcut表達(dá)式,一個方法簽名。使用注解@Pointcut標(biāo)注pointcut表達(dá)式。

@Pointcut("execution(* com.service.UserService.*(..))")
private void dataAccessOperation() {}

該聲明描述的是:匹配com.service.UserService下的所有方法的執(zhí)行。

pointcut表達(dá)式由指示器和操作參數(shù)組成。指示器有以下幾種:

  • execution,匹配joinpoint的執(zhí)行
  • within,匹配特定類下的所有joinpoint的執(zhí)行
  • this,匹配一個bean,該bean是一個給定類型的實例
  • target,匹配一個目標(biāo)對象,該對象是一個給定類型的實例
  • bean,匹配指定bean下的所有方法
  • args,匹配參數(shù)滿足要求的方法
  • @annotation,匹配由指定注解所標(biāo)注的方法

聲明Advice

Advice通常是和Pointcut表達(dá)式關(guān)聯(lián)在一起使用的。

@Component
@Aspect
public class BeforeAspectTest {
    // 定義一個Pointcut, 使用切點表達(dá)式函數(shù)來描述對哪些Joinpoint使用advise
    @Pointcut("execution(* com.service.UserService.*(..))")
    public void dataAccessOperation() {
    }
}

@Component
@Aspect
public class AdviseDefine {
    // 定義advise
    @Before("com.aspect.PointcutDefine.dataAccessOperation()")
    public void doBeforeAccessCheck(JoinPoint joinPoint) {
        System.out.println("Before advise, method: " + joinPoint.getSignature().toShortString());
    }
}

3、注解

注解Annotation是一種類似注釋的機制,在代碼中添加注解可以在之后的某個時間使用這些信息。Java虛擬機不會對注解進(jìn)行編譯,而是通過反射機制讀取注解中的信息。使用注解的主要目的是為了提高開發(fā)效率,不需要配置過多的xml文件,不必在配置文件中添加標(biāo)簽。

3.1 使用注解

需要在配置文件中增加命名空間和約束文件:

<beans ...  
xmlns:context="http://www.springframework.org/schema/context"  
xsi:schemaLocation="  
...  
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd  
">  

3.2 配置基包

告訴框架哪些類使用注解:

<context:component-scan base-package="com.spring" />

3.3 注解種類

Spring框架自帶很多注解。

持久層注解@Repository

@Repository
public class UserDao{
    // ......
}

等同于配置文件中的:

<bean id="userDao" class="com.spring.UserDao" />

服務(wù)層注解@Service

@Service(value="testService")
public classTestService {

    @Resource //相當(dāng)于自動裝配
    private UserDao userDao;
   
    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

等同于配置文件中的:

<bean id="testService" class="com.spring.UserService" />

其中,@Resource表示對象間的關(guān)系,默認(rèn)采用byName方式進(jìn)行裝配,如果找不到關(guān)聯(lián)對象,則采用byType方式裝配。

控制層注解@Controller

@Controller(value="ua")
@Scope(value="prototype")
public class UserAction {

    @Resource
    private UserService userService;

    public UserService getUserService() {
        return userService;
    }
}

等同于配置文件中的:

<bean id="ua" class="com.spring.UserAction " />

Tips:以上三層中的組件關(guān)鍵字都可以使用@Component來代替。

從Spring環(huán)境中獲取Action對象

ServletContext application =request.getSession().getServletContext();
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(application);

// 獲取控制層對象
UserAction useraction = (UserAction)ac.getBean("ua");

// 設(shè)置編碼
response.setContentType("text/html;charset=GBK");
PrintWriter out = response.getWriter();

// 分別打印三個層的對象
out.println("Action:" + userAction);
out.println("Service:" + userAction.getUserService());
out.println("Dao:" + userAction.getUserService().getUserDao());
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,414評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,169評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,722評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,465評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,823評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,000評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,554評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,295評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,513評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,722評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,125評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,430評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,237評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,482評論 2 379

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,825評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,922評論 6 342
  • 什么是Spring Spring是一個開源的Java EE開發(fā)框架。Spring框架的核心功能可以應(yīng)用在任何Jav...
    jemmm閱讀 16,531評論 1 133
  • 一. Spring概述 1.1 什么是Spring Spring是一個開源框架,Spring是于2003 年興起的...
    明天你好向前奔跑閱讀 398評論 0 1
  • http://otherserver;和http://otherserver/;有什么區(qū)別呢? 同樣訪問:http...
    264e6feedbe7閱讀 636評論 0 0