教程揭秘 | 動(dòng)力節(jié)點(diǎn)內(nèi)部Java零基礎(chǔ)教學(xué)文檔第十篇:Spring
接上期后續(xù)
本期分享第十章節(jié)
Spring
已經(jīng)分享過(guò)半了,你們都跟上了嗎?
每天都在學(xué)習(xí)嘛?
有什么不會(huì)的嘛?
今日教學(xué)文檔分享來(lái)了?

今日新篇章
【Spring】
主要內(nèi)容
1.?傳統(tǒng)項(xiàng)目結(jié)構(gòu)及問(wèn)題
2.?Spring框架的介紹
3.?Spring的IOC介紹和原理
4.?Spring的IOC的使用
5.?Spring的AOP
6.?Spring整合Mybatis
7.?聲明式事務(wù)
8.?事務(wù)的傳播性
學(xué)習(xí)目標(biāo)

?
1.?Spring框架的介紹
1.1?傳統(tǒng)的項(xiàng)目的架構(gòu)
?

在傳統(tǒng)的項(xiàng)目中,一般遵循MVC開發(fā)模型。
(1)?view層與用戶進(jìn)行交互,顯示數(shù)據(jù)或者將數(shù)據(jù)傳輸給view層。
(2)?在controller層創(chuàng)建service層對(duì)象,調(diào)用service層中業(yè)務(wù)方法。
(3)?在service層創(chuàng)建dao層對(duì)象,調(diào)用dao層中操作數(shù)據(jù)的方法。
(4)?dao層進(jìn)行具體的數(shù)據(jù)庫(kù)操作
1.2?傳統(tǒng)的項(xiàng)目架構(gòu)缺陷
程序在一定程度上存在耦合性,不利于程序的擴(kuò)展。在controller中直接創(chuàng)建了service層類的對(duì)象。如果service的業(yè)務(wù)發(fā)生了變更,那么就需要修改controller層的代碼。
?

在進(jìn)行程序的擴(kuò)展時(shí),不建議在當(dāng)前程序的基礎(chǔ)上直接修改程序,為了保證之前程序的正常,一般遵循開閉原則進(jìn)行維護(hù)性的修改,對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。
例如:用戶注冊(cè)功能。用戶注冊(cè),從賬號(hào)、密碼、手機(jī)號(hào)等信息即可。隨著行業(yè)發(fā)展,目前要求進(jìn)行實(shí)名認(rèn)證。
1.已注冊(cè)未認(rèn)證用戶登錄時(shí)進(jìn)行認(rèn)證。
2.新用戶注冊(cè)后要求進(jìn)行認(rèn)證。
為避免對(duì)已有業(yè)務(wù)的改動(dòng),可以新建一個(gè)service類,重寫注冊(cè)方法。則在controller層需要?jiǎng)?chuàng)建新的service對(duì)象。每個(gè)相關(guān)的controller層的代碼都需要改動(dòng),并且每個(gè)controller都需要?jiǎng)?chuàng)建對(duì)象,存在對(duì)象的浪費(fèi)。
面向過(guò)程--->面向?qū)ο?--->面向接口---->面向切面(組件)
ArrayList<String> aList = new ArrayList<String>();
List<String> aList = new LinkedList<String>()
1.3?解決方案
基于每個(gè)controller都要修改service的創(chuàng)建問(wèn)題,可以為service定義一個(gè)統(tǒng)一的創(chuàng)建方式,例如對(duì)象工廠模式,使用工廠創(chuàng)建對(duì)象,這樣以后使用工廠創(chuàng)建對(duì)象的對(duì)象需要維護(hù)時(shí),只需要修改對(duì)象工廠即可,且可以結(jié)合單例模式,對(duì)象工廠返回單例,這樣優(yōu)化了對(duì)象重復(fù)的浪費(fèi)問(wèn)題。
?

雖然單例工廠能夠解決對(duì)象的維護(hù)和重復(fù)問(wèn)題。但是,隨著service層的擴(kuò)大,工廠也逐漸臃腫,基本每個(gè)service會(huì)對(duì)應(yīng)一個(gè)factory?;谶@種情況,則又需要解決工廠臃腫的問(wèn)題,為此可以利用反射技術(shù),反射可以創(chuàng)建任意類的對(duì)象。但是,工廠為保證單例,只能存儲(chǔ)的對(duì)象只有一個(gè),而controller層需要使用不同的service層對(duì)象,為保證對(duì)象的有效,且反射性能相對(duì)較低,基于這樣的情況,則可以定義一個(gè)需要?jiǎng)?chuàng)建的對(duì)象的清單和一個(gè)存儲(chǔ)對(duì)象的容器,根據(jù)清單創(chuàng)建對(duì)象,然后將所有創(chuàng)建service對(duì)象進(jìn)行存儲(chǔ),每個(gè)controller只需要去容器中獲取對(duì)象即可,這樣既解決了單例問(wèn)題,也提高了性能。
?

1.3.1?代碼示例
?

1.3.2?對(duì)象清單
?
?


1.3.3?對(duì)象容器工廠
?
?
1.3.4?程序相關(guān)類
1.3.4.1?test
?
2.?Spring的介紹
2.1?簡(jiǎn)介
Spring框架是由于軟件開發(fā)的復(fù)雜性而創(chuàng)建的,初衷是為了讓軟件開發(fā)更加簡(jiǎn)單。Spring使用的是簡(jiǎn)單的JavaBean來(lái)完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限于服務(wù)器端的開發(fā)。從簡(jiǎn)單性、可測(cè)試性和松耦合性角度而言,絕大部分Java應(yīng)用都可以從Spring中受益。
Web Service,有2個(gè)顯著特點(diǎn):
1.?dāng)?shù)據(jù)格式是xml格式。
2.配置繁瑣,“笨重”,對(duì)象關(guān)聯(lián)性大,需在配置文件中各種配置。
基于這些原因,Spring框架提出了:IOC/DI(控制反轉(zhuǎn)/依賴注入),AOP(面向切面編程)。
Spring框架可在任何類型的部署平臺(tái)上為基于Java的現(xiàn)代企業(yè)應(yīng)用程序提供全面的編程和配置模型。Spring的關(guān)鍵元素是在應(yīng)用程序級(jí)別的基礎(chǔ)架構(gòu)支持:Spring專注于企業(yè)應(yīng)用程序的“管道”,以便團(tuán)隊(duì)可以專注于應(yīng)用程序級(jí)別的業(yè)務(wù)邏輯,而不必與特定的部署環(huán)境建立不必要的聯(lián)系。
2.2?Spring的核心組件 ?
?

2.2.1?核心容器
核心容器由 spring-core,spring-beans,spring-context,spring-context-support和spring-expression(SpEL,Spring 表達(dá)式語(yǔ)言,Spring Expression Language)等模塊組成,它們的細(xì)節(jié)如下:
l?spring-core 模塊提供了框架的基本組成部分,包括 IoC 和依賴注入功能。
l?spring-beans 模塊提供 BeanFactory,工廠模式的微妙實(shí)現(xiàn),它移除了編碼式單例的需要,并且可以把配置和依賴從實(shí)際編碼邏輯中解耦。
l?context 模塊建立在由 core和 beans 模塊的基礎(chǔ)上建立起來(lái)的,它以一種類似于 JNDI 注冊(cè)的方式訪問(wèn)對(duì)象。Context 模塊繼承自 Bean 模塊,并且添加了國(guó)際化(比如,使用資源束)、事件傳播、資源加載和透明地創(chuàng)建上下文(比如,通過(guò) Servelet 容器)等功能。Context 模塊也支持 Java EE 的功能,比如 EJB、JMX 和遠(yuǎn)程調(diào)用等。ApplicationContext 接口是 Context 模塊的焦點(diǎn)。spring-context-support 提供了對(duì)第三方庫(kù)集成到 Spring 上下文的支持,比如緩存(EhCache, Guava, JCache)、郵件(JavaMail)、調(diào)度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。
l?spring-expression 模塊提供了強(qiáng)大的表達(dá)式語(yǔ)言,用于在運(yùn)行時(shí)查詢和操作對(duì)象圖。它是 JSP2.1 規(guī)范中定義的統(tǒng)一表達(dá)式語(yǔ)言的擴(kuò)展,支持 set 和 get 屬性值、屬性賦值、方法調(diào)用、訪問(wèn)數(shù)組集合及索引的內(nèi)容、邏輯算術(shù)運(yùn)算、命名變量、通過(guò)名字從 Spring IoC 容器檢索對(duì)象,還支持列表的投影、選擇以及聚合等。
依賴關(guān)系圖如下:
?

2.2.2?數(shù)據(jù)訪問(wèn)/集成
數(shù)據(jù)訪問(wèn)/集成層包括 JDBC,ORM,OXM,JMS 和事務(wù)處理模塊,它們的細(xì)節(jié)如下:
(注:JDBC=Java Data Base Connectivity,ORM=Object Relational Mapping,OXM=Object XML Mapping,JMS=Java Message Service)
l?JDBC 模塊提供了 JDBC 抽象層,它消除了冗長(zhǎng)的 JDBC 編碼和對(duì)數(shù)據(jù)庫(kù)供應(yīng)商特定錯(cuò)誤代碼的解析。
l?ORM 模塊提供了對(duì)流行的對(duì)象關(guān)系映射 API 的集成,包括 JPA、JDO 和 Hibernate 等。通過(guò)此模塊可以讓這些 ORM 框架和 spring的其它功能整合,比如前面提及的事務(wù)管理。
l?OXM 模塊提供了對(duì) OXM 實(shí)現(xiàn)的支持,比如 JAXB、Castor、XML Beans、JiBX、XStream 等。
l?JMS 模塊包含生產(chǎn)(produce)和消費(fèi)(consume)消息的功能。從 Spring 4.1 開始,集成了 spring-messaging 模塊。
l?事務(wù)模塊為實(shí)現(xiàn)特殊接口類及所有的 POJO 支持編程式和聲明式事務(wù)管理。(注:編程式事務(wù)需要自己寫 beginTransaction()、commit()、rollback() 等事務(wù)管理方法,聲明式事務(wù)是通過(guò)注解或配置由 spring 自動(dòng)處理,編程式事務(wù)粒度更細(xì))
2.2.3?Web
Web 層由 Web,Web-MVC,Web-Socket 和 Web-Portlet 組成,它們的細(xì)節(jié)如下:
l?Web 模塊提供面向 web 的基本功能和面向 web 的應(yīng)用上下文,比如多部分(multipart)文件上傳功能、使用 Servlet 監(jiān)聽器初始化 IoC 容器等。它還包括 HTTP 客戶端以及 Spring 遠(yuǎn)程調(diào)用中與 web 相關(guān)的部分。
l?Web-MVC 模塊為 web 應(yīng)用提供了模型視圖控制(MVC)和 REST Web服務(wù)的實(shí)現(xiàn)。Spring 的 MVC 框架可以使領(lǐng)域模型代碼和 web 表單完全地分離,且可以與 Spring 框架的其它所有功能進(jìn)行集成。
l?Web-Socket 模塊為 WebSocket-based 提供了支持,而且在 web 應(yīng)用程序中提供了客戶端和服務(wù)器端之間通信的兩種方式。
l?Web-Portlet 模塊提供了用于 Portlet 環(huán)境的 MVC 實(shí)現(xiàn),并反映了 spring-webmvc 模塊的功能。
2.2.4?其他
還有其他一些重要的模塊,像 AOP,Aspects,Instrumentation,Web 和測(cè)試模塊,它們的細(xì)節(jié)如下:
l?AOP 模塊提供了面向方面(切面)的編程實(shí)現(xiàn),允許你定義方法攔截器和切入點(diǎn)對(duì)代碼進(jìn)行干凈地解耦,從而使實(shí)現(xiàn)功能的代碼徹底的解耦出來(lái)。使用源碼級(jí)的元數(shù)據(jù),可以用類似于.Net屬性的方式合并行為信息到代碼中。
l?Aspects 模塊提供了與 AspectJ 的集成,這是一個(gè)功能強(qiáng)大且成熟的面向切面編程(AOP)框架。
l?Instrumentation 模塊在一定的應(yīng)用服務(wù)器中提供了類 instrumentation 的支持和類加載器的實(shí)現(xiàn)。
l?Messaging 模塊為 STOMP 提供了支持作為在應(yīng)用程序中 WebSocket 子協(xié)議的使用。它也支持一個(gè)注解編程模型,它是為了選路和處理來(lái)自 WebSocket 客戶端的 STOMP 信息。
l?測(cè)試模塊支持對(duì)具有 JUnit 或 TestNG 框架的 Spring 組件的測(cè)試。
3.?Spring的IOC的使用 ?IOC、DI
IOC:控制反轉(zhuǎn)。將對(duì)象的創(chuàng)建、初始化、銷毀等一系列的生命周期過(guò)程交給spring管理。
結(jié)婚:
方式1: 自己找女生--------------->吃飯、逛街、看電影、送回家等--------->結(jié)婚
(同學(xué)、同事、公交地鐵1個(gè)月-3個(gè)月) ???????????半年-1年半 ?????????????????1天
方式2: 媒婆(1個(gè)月)------------------------>結(jié)婚(1天)
?
吃飯:
方式1: ?買菜、買米(30min-1h)---->蒸飯、洗菜、切菜、炒菜(1個(gè)小時(shí))--->吃(15-30min)
方式2: ?定外賣----------------->吃(15-30min)
?
面向過(guò)程----->面向?qū)ο?---->面向接口----->面向組件(面向切面)-->面向服務(wù)--->面向百度
3.1?基本使用
3.1.1?創(chuàng)建項(xiàng)目并導(dǎo)入spring IoC相關(guān)jar包

3.1.2?創(chuàng)建User類
?
?
3.1.3?創(chuàng)建Spring的核心配置文件spring-context.xml/applicationContext.xml
3.1.4?編寫測(cè)試程序
3.2?Bean標(biāo)簽屬性介紹
3.2.1?id
是 bean的唯一標(biāo)識(shí) 一個(gè)bean,其id 值只能有一個(gè) 。整個(gè)IOC 容器id 值不允許重復(fù),使用名稱作為key。
3.2.2?name
一個(gè)bean的名稱,可以存在多個(gè),多個(gè)之間使用逗號(hào)分隔。不論bean有沒有定義name屬性,默認(rèn)id都會(huì)當(dāng)做name。
3.2.3?class
bean的具體的類型,包名和類名組成。
3.2.4?scope
bean的作用域:如果不寫scope,則默認(rèn)為單例
prototype :非單例,每次獲取都會(huì)創(chuàng)建一個(gè)新的bean對(duì)象。
singleton : 單例,多次獲取永遠(yuǎn)同一個(gè)bean,?默認(rèn)值。
request : 一次請(qǐng)求,基于web項(xiàng)目的bean的作用域。
session : 一次會(huì)話,基于web項(xiàng)目的bean的作用域。
3.2.5?lazy-init
延遲初始化(懶加載),默認(rèn)只要加載了配置文件。bean對(duì)象就會(huì)被初始化,lazy-init則是獲取時(shí)才會(huì)初始化。只針對(duì)單例模式有效,非單例每次獲取都會(huì)創(chuàng)建,沒有延遲初始化的意義
3.2.6?depends-on
初始化時(shí)依賴的對(duì)象,當(dāng)前對(duì)象初始化前需先初始化depends-on指定的對(duì)象
3.2.7?init-method
對(duì)象初始化后,調(diào)用的方法
3.2.8?destroy-method
對(duì)象銷毀時(shí),調(diào)用的方法
3.2.9?autowire
屬性自動(dòng)裝配
byName 根據(jù)屬性名稱裝配
byType 根據(jù)類型裝配
3.2.10?autowire-candidate
是否允許作為自動(dòng)裝配的候選項(xiàng)
true 作為自動(dòng)裝配的候選項(xiàng)
false 不作為自動(dòng)裝配的候選項(xiàng)
3.2.11?primary
優(yōu)先使用該bean,因?yàn)镾pring需要支持使用類型查找對(duì)象,在一個(gè)大類型下,可能存在多個(gè)小類型。如果根據(jù)大類型裝配屬性時(shí),不知道使用哪個(gè)具體的對(duì)象,則可以根據(jù)primary設(shè)置優(yōu)先級(jí)。
3.2.12?代碼示例
?
3.3?Bean對(duì)象創(chuàng)建的4種方式
3.3.1?構(gòu)造方法創(chuàng)建
使用構(gòu)造方法創(chuàng)建bean對(duì)象,是spring默認(rèn)的創(chuàng)建方式。
<!-- 使用構(gòu)造方法創(chuàng)建對(duì)象 -->
<bean id="user" class="com.bjpowernode.domian.User" />
?
3.3.2?靜態(tài)工廠創(chuàng)建
?
3.3.3?非靜態(tài)工廠創(chuàng)建
?
3.3.4?注解創(chuàng)建
Spring為簡(jiǎn)化對(duì)象的創(chuàng)建方式,提供了注解。
3.3.4.1?組件注解:
3.3.4.1.1?@Component(“bs”) ??<bean id=”bs”?class=”xxxx”>
表示該類為一個(gè)被Spring管理的組件。但是,由于在開發(fā)中為了讓代碼的可讀性更高。
Spring基于分層思想,將需要?jiǎng)?chuàng)建的組件分為以下幾類:
3.3.4.1.2?@Controller
@Controller注解,標(biāo)識(shí)該類是controller層的類。并且,注意在使用SpringMVC時(shí),所有的Constroller,必須使用@Controller注解。
3.3.4.1.3?@Service
@Service注解,標(biāo)識(shí)該類是業(yè)務(wù)層的類。
3.3.4.1.4?@Respository
@Respository注解,標(biāo)識(shí)該類是操作數(shù)據(jù)層的類。
注意:
以上注解是Spring中定義的創(chuàng)建對(duì)象的注解,都可以創(chuàng)建對(duì)象,如果該類有明確的作用,有自己所屬的層,則建議使用相應(yīng)的注解,如果實(shí)在無(wú)法區(qū)分該類所屬層,可以使用@Component注解。
3.3.4.2?注解使用步驟
3.3.4.2.1?開啟組件掃描
在spring的核心配置文件中,開啟注解掃描,讓Spring將被注解修飾的類,創(chuàng)建對(duì)相關(guān)。
xml頭部
?
3.3.4.2.2?添加注解
?
3.3.5?什么時(shí)候使用XML配置和注解 ?
能使用注解時(shí),就使用了注解,注解非常方便。但是,在第三方的類中,是無(wú)法使用注解的。因?yàn)闊o(wú)法在別人提供的源碼上加上Spring注解,此時(shí)只能使用XML配置的形式,配置第三方類的Bean信息。
3.4?IOC屬性注入的3種方式
為對(duì)象屬性設(shè)置值,就是屬性注入。
3.4.1?構(gòu)造方法屬性注入:DI(依賴注入,給對(duì)象的屬性賦值) ?
?
?
3.4.2?set方法屬性注入
?
3.4.3?注解屬性注入
在spring中,為了簡(jiǎn)化屬性的注入,Spring提供注解:@Autowired,Spring會(huì)自動(dòng)從IOC容器中,為這個(gè)屬性查找相應(yīng)類型的值,進(jìn)行注入。
1.?開啟包的注解掃描
<context:component-scan base-package="com.*" />
2.?使用注解
?
注意:
在使用自動(dòng)注入時(shí),可以在bean標(biāo)簽上,配置autowire,但是此時(shí)必須有該屬性的set方法,@Autowired注解,是不需要set方法的。
如果是在xml中注入對(duì)象,值使用ref屬性。value屬性,只支持boolean,數(shù)字,字符串等。
3.5?常見類型的屬性注入
在Spring中,提供了豐富的標(biāo)簽,進(jìn)行各種屬性的注入。常見的類型:
數(shù)字、字符串、boolean、數(shù)組、set、list、map、properties。
3.6?使用IOC容器,改造傳統(tǒng)項(xiàng)目
3.6.1?xml配置版
3.6.1.1?創(chuàng)建項(xiàng)目并加入依賴
?

3.6.1.2?項(xiàng)目結(jié)構(gòu)
?

3.6.1.3?配置文件
?
3.6.1.4?controller
?
3.6.1.5?dao
?
3.6.1.6?service
?
?
3.6.1.7?test
?
3.6.2?注解版
3.6.2.1?配置文件
?
3.6.2.2?controller
?
3.6.2.3?dao
?
?
3.6.2.4?service
?
3.6.2.5?test
4.?AOP
com.powernode.aadenglu
Login: login():登錄方法
?
com.powernode.anquan
Security: isSecurity():檢測(cè)操作環(huán)境是否安全
?
com.powernode.bmapper ?
CBCBankMapper(核心類): selectMoney() updateMoney() updateInvest() update2Tel()
?
com.powernode.crizhi
Logger: log():記錄用戶操作細(xì)節(jié)
?
com.powernode.dqinli
Clean :cleanResource():清理緩存
?
Expt: ?handExpt()
?
4.1?AOP簡(jiǎn)介:面向切面(面向組件)
DefaultAopProxyFactory
代理
靜態(tài)代理
靜態(tài)代理,每個(gè)被代理類都需要?jiǎng)?chuàng)建對(duì)應(yīng)的代理類。隨著程序的擴(kuò)展,代理類也會(huì)增多,臃腫,維護(hù)量變多,為了解決這個(gè)問(wèn)題,Java中,提供了動(dòng)態(tài)代理技術(shù),開發(fā)者不需要自己定義代理類,代理類由JDK動(dòng)態(tài)的創(chuàng)建,開發(fā)只需要指定被代理的類即可。
切面(aspect):除了核心類以外的其他類稱之為切面
通知(advisor):切面中的方法稱之為通知
核心類:一個(gè)項(xiàng)目中不能省略的模塊類
核心方法:核心類中的方法稱之為核心方法
連接點(diǎn):核心類中的某一個(gè)方法
切入點(diǎn)(pointcut):某個(gè)包下的某個(gè)類下的某一批方法
代理(proxy):將多個(gè)切面與核心類組合在一起,形成一個(gè)新的類,這個(gè)類稱之為代理類
織入(weaver):書寫代理類的過(guò)程稱之為織入
4.2?動(dòng)態(tài)代理
4.2.1?JDK動(dòng)態(tài)代理
4.2.1.1?Proxy
該類提供了方法創(chuàng)建代理類和代理類的對(duì)象的方法
創(chuàng)建一個(gè)代理類并返回代理類對(duì)象
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) ?
loader?: 類加載器,指定類加載器,是為了精確的定位類
interfaces?: 接口Class類,使用JDK的反射,必須要有接口
h?:InvocationHandler ,代理的處理器,每個(gè)代理類都有一個(gè)關(guān)聯(lián)的處理器
4.2.1.2?InvocationHandler
是每個(gè)代理類對(duì)應(yīng)的處理器
Object ?方法調(diào)用的返回值,可以作為被代理的方法調(diào)用的返回值
proxy : 代理類對(duì)象
method : 目標(biāo)類中被代理的方法
args : 目標(biāo)類中被代理的方法的運(yùn)行參數(shù)
Object invoke(Object proxy,Method method,Object[] args)
4.2.1.3?代碼示例
4.2.1.3.1?目標(biāo)類接口
?
?
4.2.1.3.2?目標(biāo)類
?
?
4.2.1.3.3?代理類處理器
?
?
4.2.1.3.4?測(cè)試類
?
4.2.1.3.5?生成代理類源碼
?
4.2.1.3.6?JDK動(dòng)態(tài)代理的不足
在JDK中使用動(dòng)態(tài)代理,必須有類的接口。因?yàn)樯傻拇硇枰獙?shí)現(xiàn)這個(gè)接口,這樣我們生成的代理類對(duì)象,才能轉(zhuǎn)化為代理目標(biāo)的接口對(duì)象,然后根據(jù)接口中的方法,調(diào)用處理器中invoke方法。
?

4.2.2?Cglib動(dòng)態(tài)代理
為了彌補(bǔ)JDK動(dòng)態(tài)代理的不足,第三方組織封裝一套工具包,cglib的工具包,這套包不基于接口,基于父子繼承,通過(guò)重寫的形式擴(kuò)展方法,但是這個(gè)子類工具自動(dòng)生成的。
早期,Cglib動(dòng)態(tài)代理,性能相于JDK的動(dòng)態(tài)代理高一些。JDK進(jìn)行一些列優(yōu)化,目前Spring默認(rèn)使用的動(dòng)態(tài)代理JDK,也支持Cglib。
4.2.2.1?Cglib動(dòng)態(tài)代理的使用
4.2.2.1.1?MethodInterceptor ?
cglib中,提供的對(duì)方法執(zhí)行攔截的接口。其中intercept是對(duì)具體方法進(jìn)行攔截處理的方法。
?public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,
???????????????????????????????MethodProxy proxy)
Object ?: 方法執(zhí)行返回的結(jié)果
obj?:增強(qiáng)類的對(duì)象
method?:目標(biāo)方法
proxy :用于回調(diào)的方法的對(duì)象
4.2.2.1.2?代碼示例
4.2.2.1.2.1?導(dǎo)入jar包
?
4.2.2.1.2.2?創(chuàng)建被代理目標(biāo)類
?
4.2.2.1.2.3?方法攔截器
?
4.2.2.1.2.4?測(cè)試類
?
4.2.2.2?動(dòng)態(tài)代理的不足
不論是JDK的動(dòng)態(tài)代理,還是第三方cglib動(dòng)態(tài)代理,都需要開發(fā)者編寫代碼處理程序。程序結(jié)構(gòu)基本上大同小異,重復(fù)造輪子?;谶@樣的情況,在Spring中,提供了2種方式:xml配置形式和注解形式,使用動(dòng)態(tài)代理。這種模式就是Spring Aop技術(shù)。其底層依然是動(dòng)態(tài)代理。
4.3?Spring的AOP配置
在Spring中,AOP的配置主要分為2類:xml配置和注解配置
XML配置也分為兩種,一種Spring的原生支持,一種是Spring的aspects這個(gè)相關(guān)的框架。
4.3.1?AOP的相關(guān)概念
連接點(diǎn)(JoinPoint):所謂連接點(diǎn)是指那些被攔截的點(diǎn),而spring中這些點(diǎn)就是指方法,因?yàn)閟pring只支持方法類型的連接點(diǎn)。
切入點(diǎn)(PointCut):所謂切入點(diǎn)就是指我們要對(duì)那些JoinPoint進(jìn)行攔截的定義,指的是具體的攔截的位置
增強(qiáng)/通知(Advice)?: 增強(qiáng)就是對(duì)具體的連接點(diǎn)進(jìn)行擴(kuò)展的功能。由于一般對(duì)方法進(jìn)行增強(qiáng),分為在方法前執(zhí)行或者方法后,或者發(fā)生異常執(zhí)行等等,所以增強(qiáng)被分為:前置增強(qiáng)(前置通知)、后置增強(qiáng)(后置通知)、環(huán)繞通知(環(huán)繞增強(qiáng))、異常增強(qiáng)(異常通知)
引介(Introduction):引介是一種特殊的Advice,在不修改代碼的前提下,引介可以在運(yùn)行期為類動(dòng)態(tài)的添加一些方法或Field.
目標(biāo)(Target)?:被代理的類(需要增強(qiáng)類)
織入(Weaving)?:把Advice應(yīng)用到Target的過(guò)程
代理(Proxy):使用AOP配置后產(chǎn)生的代理類
切面(Aspect):切點(diǎn)和增強(qiáng)整合形成了切面
?

4.3.2?Spring自身AOP具體配置
4.3.2.1?引入aop相關(guān)jar包
?
4.3.2.2?定義增強(qiáng)類
4.3.2.2.1?前置增強(qiáng)-MethodBeforeAdvice
4.3.2.2.2?后置增強(qiáng)-AfterReturningAdvice
?
4.3.2.2.3?環(huán)繞增強(qiáng)-MethodInterceptor
?
4.3.2.2.4?異常增強(qiáng)-ThrowsAdvice
?
4.3.2.3?目標(biāo)類
?
4.3.2.4?aop配置
?
4.3.2.5?測(cè)試類
?
4.3.3?AspectJ框架AOP配置
在原生的spring中,每種增強(qiáng)都需要單獨(dú)定義一個(gè)類實(shí)現(xiàn)相應(yīng)的接口。增強(qiáng)類本身就更龐大,而且方法的名稱是固定的。基于這種情況,AspectJ提供了相對(duì)更加靈活的方式。
在AspectJ中,只需要定義一個(gè)增強(qiáng)類即可,并且方法的名稱可以任意定義。
4.3.3.1?引入相關(guān)jar
?
?
4.3.3.2?編寫增強(qiáng)類
?
?
4.3.3.3?編寫目標(biāo)類
?
4.3.3.4?配置AspectJ的增強(qiáng)配置
?
4.3.3.5?進(jìn)行測(cè)試
?
?
4.3.4?AspectJ的AOP注解方式
4.3.4.1?引入相關(guān)jar包
?
4.3.4.2?定義增強(qiáng)類
?
4.3.4.3?目標(biāo)類
?
?
4.3.4.4?開啟相關(guān)注解
?
?
4.3.4.5?測(cè)試類
5.?Spring整合Mybatis
Spring整合Mybatis就是將Mybatis交給Spring進(jìn)行管理,將Mybatis的SqlSession對(duì)象,放入IOC容器中,并且可以利用自動(dòng)裝配功能,為每個(gè)數(shù)據(jù)庫(kù)操作層,注入SqlSession。并且Spring內(nèi)置可以有代理的,可以根據(jù)SqlSession對(duì)象及數(shù)據(jù)操作接口,創(chuàng)建Mapper接口的代理對(duì)象,此時(shí)Mapper的代理在IOC容器中,那么可以將Mapper接口的對(duì)象注入到Service中。
5.1?多XML版
使用配置文件版本,Mybatis配置文件和Spring配置文件是單獨(dú)的。
5.1.1?引入相關(guān)jar包
5.1.1.1?spring相關(guān)jar包
5.1.1.2?mybatis相關(guān)jar包
?
5.1.1.3?數(shù)據(jù)庫(kù)相關(guān)jar包
?
5.1.1.4?日志相關(guān)jar包
5.1.1.5?spring和mybatis整合包
5.1.1.6?mybatis分頁(yè)插件包
5.1.2?相關(guān)類
5.1.2.1?domain
?
5.1.2.2?mapper
?
5.1.2.3?service
?
5.1.2.4?測(cè)試類
?
5.1.3?相關(guān)配置文件
5.1.3.1?jdbc配置文件
5.1.3.2?日志配置文件
5.1.3.3?mybatis核心配置文件
5.1.3.5?spring核心配置文件
5.2?Spring配置文件版
使用Spring的配置文件,取代mybatis的核心配置文件。
導(dǎo)入的jar包和相關(guān)類完全一致,jdbc配置文件和日志配置文件也相同。只是將mybatis的核心配置文件中的配置,移入到spring的核心配置文件中。
5.2.1?Spring核心配置文件
?
5.2.2?配置日志
?
6.?聲明式事務(wù)
在spring中,spring可以管理數(shù)據(jù)源,管理連接,spring也可以管理事務(wù),并且spring單獨(dú)對(duì)事務(wù)分了一個(gè)模塊進(jìn)行管理。并且,Spring簡(jiǎn)化了事務(wù)開發(fā),只需要通過(guò)配置的方式,Spring即可對(duì)事務(wù)進(jìn)行統(tǒng)一完善的管理,Spring的事務(wù)管理基于Spring的AOP技術(shù)。
Spring的聲明式事務(wù),有兩種方式:xml配置、注解
6.1?XML配置方式
6.2?注解版聲明式事務(wù)
在Spring中,為簡(jiǎn)化事務(wù)開發(fā),提供了注解:@Transactional,該注解可以指定在類上,在類上,該類中的所有方法都會(huì)使用事務(wù),該注解也可以指定方法上,該方法會(huì)使用事務(wù)。使用非常簡(jiǎn)單,只需:
1.?配置事務(wù)管理器
2.?開啟注解事務(wù)
3.?在需要使用事務(wù)的地方使用@Transactional
6.2.1?配置類
?
6.2.2?service代碼
7.?2

注意:
事務(wù)的傳播行為,是指事務(wù)會(huì)發(fā)生傳遞。例如:A方法存在事務(wù),A調(diào)用B方法,那么B方法也會(huì)在事務(wù)中執(zhí)行,這種就是事務(wù)的傳播行為。

更多干貨我們下期再說(shuō)!
下期會(huì)分享
第十一章節(jié)
SpringMVC
相關(guān)知識(shí)~
下期見!
