么是 Spring Boot ?
解釋一下:Spring Boot 可以構建一切。Spring Boot 設計之初就是為了最少的配置,最快的速度來啟動和運行 Spring 項目。Spring Boot 使用特定的配置來構建生產就緒型的項目。
Spring Boot 的特性:
使用 Spring 項目引導頁面可以在幾秒構建一個項目
方便對外輸出各種形式的服務,如 REST API、WebSocket、Web、Streaming、Tasks
非常簡潔的安全策略集成
支持關系數據庫和非關系數據庫
支持運行期內嵌容器,如 Tomcat、Jetty
強大的開發包,支持熱啟動
自動管理依賴
自帶應用監控
支持各種 IED,如 IntelliJ IDEA、NetBeans
Spring Boot 快速入門
(1)訪問 http://start.spring.io/。
(2)選擇構建工具 Maven Project、Spring Boot 版本 1.5.8 及一些工程基本信息,可參考下圖:
(3)單擊 Generate Project 按鈕并下載項目壓縮包。
(4)解壓后,單擊 Eclipse,Import | Existing Maven Projects | Next | 選擇解壓后的文件夾 | Finsh 命令,OK Done!
(5)如果使用的是 Idea,單擊 File | New | Model from Existing Source.. | 選擇解壓后的文件夾 | OK 命令, 選擇 Maven ,一路 Next,OK Done!
如果讀者使用的是 Idea 工具,也可以這樣:
(1)單擊 File | New | Project… 命令,彈出新建項目框。
(2)選擇 Spring Initializr 選項,單擊 Next 按鈕,也會出現上述類似的配置界面,Idea 幫我們做了集成。
(3)填寫相關內容后,單擊 Next 按鈕,選擇依賴的包再單擊 Next 按鈕,最后確定信息無誤單擊 Finish 按鈕。
對上面的配置做一個解釋:
第一個選擇框選擇創建以 Maven 構建項目,還是以 Gradle 構建項目,這是兩種不同的構建方式,其中 Gradel 配置內容更簡潔一些,并且包含了 Maven 的使用,不過日常使用 Maven 居多。
第二個選擇框選擇編程語言,現在支持 Java、Kotlin 和 Groovy。
第三個選擇框選擇 Spring Boot 版本,可以看出 Spring Boot 2.0 已經到了第五個里程碑了。在實際使用中,我們會優先使用穩定版本,1.0 的最新穩定版本是 1.5.8,也是我們演示使用的版本。
下面就是項目的配置信息了。
Group:一般填寫公司域名,比如百度公司填 com.baidu,演示使用 com.neo。
Artifact:可以理解為項目的名稱,可以根據實際情況來填,本次演示填寫 helloWorld。
Dependencies:在這塊添加我們項目所依賴的 Spring Boot 組件,可以多選。本次選擇 Web、devtools 兩個模塊。
項目結構介紹
如上圖所示,Spring Boot 的基礎結構共三個文件:
src/main/java:程序開發以及主程序入口
src/main/resources:配置文件
src/test/java:測試程序
另外,Sping Boot 建議的目錄結果如下:
root package 結構:com.example.myproject
com.example.myproject 目錄下:
Application.java:建議放到根目錄下面,是項目的啟動類,Spring Boot 項目只能有一個 main 方法。
comm:目錄建議放置公共的類,如全局的配置文件、工具類等。
domain:目錄主要用于實體(Entity)與數據訪問層(Repository)。
repository:數據庫訪問層代碼。
service:該層主要是業務類代碼。
web:該層負責頁面訪問控制。
resources 目錄下:
static:目錄存放 Web 訪問的靜態資源,如 JS、CSS、圖片等。
templates:目錄存放頁面模板。
application.properties:項目的配置信息。
test 目錄存放單元測試的代碼;pom.xml 用于配置項目依賴包,以及其他配置。
采用默認配置可以省去很多設置,當然也可以根據自己的喜好來進行更改。最后,啟動 Application main 方法,至此一個 Java 項目搭建好了!
簡單 Web 開發
(1)可以在 Spring Initializr 上面添加,也可以手動在 pom.xml 中添加:
pom.xml 文件中默認有兩個模塊:
spring-boot-starter:核心模塊,包括自動配置支持、日志和 YAML;
spring-boot-starter-test:測試模塊,包括 JUnit、Hamcrest、Mockito。
(2)編寫 controller 內容:
@RestControllerpublic class HelloWorldController
{ @RequestMapping("/hello")
public String hello
{
return "Hello World"; }}
@RestController
的意思就是 controller 里面的方法都以 json 格式輸出,不用再配置什么 jackjson 的了!
如果配置為@Controller
就代表著輸出為頁面內容。
(3)啟動主程序,打開瀏覽器訪問 http://localhost:8080/hello,就可以看到以下內容,是不是很簡單!
Hello World
(4)如果我們想傳入參數怎么辦?
@RestControllerpublic class HelloWorldController
{ @RequestMapping("/hello")
public String index(String name)
{
return "Hello World, " +name; }}
重新啟動項目,訪問 http://localhost:8080/hello?name=neo,返回內容如下:
Hello World,neo
經過上一個測試發現,修改 controller 內相關代碼,就需要重新啟動項目才能生效,這樣做很麻煩是不是,別著急。Spring Boot 提供了另外一個組件來解決。
熱部署
熱啟動就需要用到我們在一開始引入的另外一個組件:devtools。它是 Spring Boot 提供的一組開發工具包,其中就包含我們需要的熱部署功能。但是在使用這個功能之前還需要再做一些配置。
(1)在 dependency 中添加 optional 屬性,并設置為 true:
(2)在 plugin 中配置另外一個屬性 fork,并且配置為 true:
OK,以上兩步配置完成,如果讀者使用的是 Eclipse,那么恭喜你大功告成了。
如果讀者使用的是 Idea 還需要做以下配置。
(3)配置 Idea
選擇 File-Settings-Compiler 勾選 Build project automatically
,低版本 Idea 勾選make project automatically
。
使用快捷鍵:CTRL + SHIFT + A
輸入Registry
找到選項compile.automake.allow.when.app.running
勾選
全部配置完成后,Idea 就支持熱部署了,大家可以試著去改動一下代碼就會發現 Spring Boot 會自動重新加載,再也不需要我們手動點擊重新部署了。
為什么 Idea 需要多配置后面這一步呢,因為 Idea 默認不是自動編譯的,需要我們手動去配置后才會自動編譯,而熱部署依賴于項目的自動編譯功能。
該模塊在完整的打包環境下運行的時候會被禁用。如果使用 java -jar 啟動應用或者用一個特定的 classloader 啟動,它會認為這是一個“生產環境”。
單元測試
單元測試在日常開發中是必不可少的,一個牛逼的程序員,單元測試寫得也是杠杠的。下面來看下 Spring Boot 對單元測試又做了哪些支持?
如果我們只想運行一個 hello World,只需要一個注解就可以。在 src/test 目錄下新建一個 HelloTests 類,代碼如下:
public class HelloTest
{ @Test public void hello
{ System.out.println("hello world"); }}
單擊右鍵“運行”按鈕,會發現控制臺輸出:hello world。僅僅只需要了一個注解。但是如果我們需要測試 web 層的請求呢?Spring Boot 也給出了支持。
以往我們在測試 web 請求的時候,需要手動輸入相關參數在頁面測試查看效果,或者自己寫 post 請求。在 Spring Boot 中,Spring 給出了一個簡單的解決方案;使用 mockmvc 進行 web 測試,mockmvc 內置了很多工具類和方法,可以模擬 post、get 請求,并且判斷返回的結果是否正確等,也可以利用print
打印執行結果。
@SpringBootTest
public class HelloTest
{
private MockMvc mockMvc;
@Before
public void setUp t
hrows Exception
{ mockMvc = MockMvcBuilders.standaloneSetup(new HelloWorldController).build; }
@Test public void getHello
throws Exception
{ mockMvc.perform(MockMvcRequestBuilders.post("/hello?name=小明").accept(MediaType.APPLICATION_JSON_UTF8)).andDo(print); }}
在類的上面添加@SpringBootTest
,系統會自動加載 Spring Boot 容器。在日常測試中,我們就可以注入 bean 來做一些局部業務的測試。MockMvcRequestBuilders
可以 post、get 請求,使用print
方法會將請求和相應的過程都打印出來,如下:
MockHttpServletRequest: HTTP Method = POST Request URI = /hello Parameters = {name=[neo]} Headers = {}Handler: Type = com.neo.helloWorld.web.HelloWorldController Method = public java.lang.String com.neo.helloWorld.web.HelloWorldController.hello(java.lang.String)...MockHttpServletResponse: Status = 200
Error message =
Headers = {Content-Type=[text/plain;charset=ISO-8859-1], Content-Length=[16]} Content type = text/plain;
charset=ISO-8859-1
Body = Hello World ,neo Forwarded URL =
Redirected URL =
Cookies =
從返回的Body = Hello World ,neo
可以看出請求成功。
總結
使用 Spring Boot 可以非常方便、快速搭建項目,而不用關心框架之間的兼容性、適用版本等各種問題,我們想使用任何東西,僅僅添加一個配置就可以,所以使用 Sping Boot 非常適合構建微服務。
建議大家使用 Idea 開發 Spring Boot 項目,Eclipse 對 Spring Boot 項目支持并不好,并且使用 Eclipse 偶爾會出現一些詭異的問題,影響初學者的學習。
關于完整的學習 Spring Boot 路徑,我寫了結構更加清晰,知識點更加系統的課程。
面完成了API服務(雖然這個API沒什么用)。接下去來個WEB服務,在前面項目中加上個頁面。這章目標是通過訪問一個URL展示一個界面,從服務端傳遞參數值到界面中展示動態數據。這里還會涉及到webjars的應用。
目錄與文件
在項目src/main/resources目錄下創建兩個目錄,分別是templates各static,templates 存放模板文件,static 存放靜態文件。
目錄
在static目錄放入一張圖片,圖片名稱為001.jpg,啟動項目。打開瀏覽器訪問http://localhost/001.jpg
訪問資源
spring boot會默認從static查找靜態資源,在這里還可以放css,js,html等文件,都可以直接訪問到。但是,這里的html文件只能是靜態頁面,服務端不能傳值到界面中。
templates中加入一個index.html,內容如下<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>這里是標題</title> </head> <body> <div> <p>這是首頁</p> </div> </body> </html>
重啟服務,瀏覽器中訪問http://localhost/index.html
404
找不到頁面,如果index.html放到static目錄中是可以訪問的。templates目錄中的文件是不能直接訪問。下面講到這么訪問templates中的文件。
當前目錄
目錄
使用模板
訪問templates文件,首先要引入模板引擎。這里使用thymeleaf,在pom.xml文件中包含thymeleaf組件。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
如圖
增加package:com.biboheart.demos.web,在package中創建class:PageController
package com.biboheart.demos.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class PageController { @RequestMapping(value = {"/", "/home"}) public String home() { return "index"; } }
@Controller表示這是一個SpringMVC的控制器
@RequestMapping(value = {"/", "/home"}) 表示訪問路徑"/"或"/home"都指向home函數,home返回"index"頁面,即templates/index.html模板生成的頁面。
重新啟動服務,在瀏覽器中訪問 http://localhost/home
home頁面
這時候,頁面展示的是index.html的內容。向頁面傳值
這里用Model對象傳值到模板中
調整controller的實現
package com.biboheart.demos.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class PageController { @RequestMapping(value = {"/", "/home"}) public String home(Model model, String name) { model.addAttribute("name", name); return "index"; } }
在函數中增加兩個參數,Model model用于向模板傳遞值,name用于接收請求參數。model.addAttribute("name", name);將接收到的值通過model傳遞到模板中。
模板文件index.html中接收并顯示name的值。
<!DOCTYPE html> <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>這里是標題</title> </head> <body> <div> <p>這是首頁</p> <p>歡迎你:<span th:text="${name}"></span></p> </div> </body> </html>
重新啟動服務,在瀏覽器中訪問http://localhost/home?name=biboheart
參數
index.html中的<span th:text="${name}"></span>,展示Model中的name的值。使用webjars
在pom.xml中包含webjars,并且包含jquery,bootstrap
<dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator</artifactId> <version>0.34</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.3.1</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.7-1</version> </dependency>
界面中使用bootstrap
<!DOCTYPE html> <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>這里是標題</title> <script src="/webjars/jquery/jquery.min.js"></script> <script src="/webjars/bootstrap/js/bootstrap.min.js"></script> <link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css"/> </head> <body> <div class="container"> <div class="jumbotron"> <h1>歡迎你:<span th:text="${name}"></span></h1> <p>這是首頁</p> </div> </div> </body> </html>
重新啟動項目,在瀏覽器中訪問http://localhost/home?name=biboheart
bootstrap效果
模板中包含靜態資源
將靜態資源001.jpg圖片在模板中顯示,修改后index.html文件如下
IOC: 控制反轉
即控制權的轉移,將我們創建對象的方式反轉了,以前對象的創建時由我們開發人員自己維護,包括依賴關系也是自己注入。使用了spring之后,對象的創建以及依賴關系可以由spring完成創建以及注入,反轉控制就是反轉了對象的創建方式,從我們自己創建反轉給了程序創建(spring)
DI: Dependency Injection 依賴注入
spring這個容器中,替你管理著一系列的類,前提是你需要將這些類交給spring容器進行管理,然后在你需要的時候,不是自己去定義,而是直接向spring容器索取,當spring容器知道你的需求之后,就會去它所管理的組件中進行查找,然后直接給你所需要的組件.
實現IOC思想需要DI做支持
注入方式: 1.set方式注入 2.構造方法注入 3.字段注入
注入類型: 1.值類型注入 2.引用類型注入
好處:
1.降低組件之間的耦合度,實現軟件各層之間的解耦.
2.可以使容器提供眾多服務如事務管理消息服務處理等等。當我們使用容器管理事務時,開發人員就不需要手工 控制事務,也不需要處理復雜的事務傳播
3.容器提供單例模式支持,開發人員不需要自己編寫實現代碼.
4.容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能
5.容器提供眾多的輔佐類,使這些類可以加快應用的開發.如jdbcTemplate HibernateTemplate
BeanFactory接口
(1) spring的原始接口,針對原始接口的實現類功能較為單一
(2)BeanFactory接口實現類的容器,特點是每次在獲得對象時才會創建對象
ApplicationContext接口
(1)每次容器啟動時就會創建容器中配置的所有對象
(2)提供了更多功能
(3)從類路徑下加載配置文件: ClassPathXmlApplicationContext
從硬盤的絕對路徑下加載配置文件:FileSystemXmlApplication
bean元素:使用該元素描述需要spring容器管理對象
name屬性:給被管理的對象起個名字,獲得對象時getBean("name值")
class屬性:被管理對象的完整類名
id屬性:與name屬性一模一樣,名稱不可重復,不能使用特殊字符
name和id之間的一些注意點:
1、配置兩個相同的 id 或者 name 都不能通過。
2、如果既配置了 id ,也配置了 name ,則兩個都生效。如果id和name都沒有指定,則用類全名作為name,如<bean class="com.stamen.BeanLifeCycleImpl">,則你可以通過getBean("com.stamen.BeanLifeCycleImpl")返回該實例。
3、如果配置基本類的時候,注解和配置文件都使用的時候,注解和配置文件中 name 相同的時候, 則兩個沖突,配置文件生效。
如果配置基本類的時候,注解和配置文件都使用的時候,注解和配置文件中 name 不相同的時候, 則兩個不沖突,都能夠生效。
(1)scope屬性
(1)singleton 默認值
單例對象 :被標識為單例的對象在spring容器中只會存在一個實例
(2)prototype
多例原型:被標識為多例的對象,每次在獲得才會被創建,每次創建都是新的對象
(3)request
Web環境下,對象與request生命周期一致
(4)session
Web環境下,對象與session生命周期一致
總結:絕大多數情況下,使用單例singleton(默認值),但是在與struts整合時候,務必要用prototype多例,因為struts2在每次請求都會創建一個新的Action,若為單例,在多請求情況下,每個請求找找spring拿的都是同一個action。
(2)生命周期屬性(了解)———初始化和銷毀
(1)配置一個方法作為生命周期初始化方法,spring會在對象創建之后立刻調用 init-method
(2)配置一個方法作為生命周期的銷毀方法,spring容器在關閉并銷毀所有容器中的對象之前調用destory-method
<bean init-method=“init” destory-method=“destory”></bean> 對應注解為@PostConstruct
<bean name=“hello” class=“完整類名”></bean> 對應注解為@PreDestory
(3)模塊化配置,即分模塊配置(導入其他spring配置文件)
<beans>
<import resource = “spring配置文件的全路徑名” />
</beans>
<bean name="user" class="cn.itcats.UserFactory" factory-method="createUser"></bean>
<bean name="user2" factory-bean="userFactory" factory-method="createUser"></bean> <bean name=“userFactory” class=“cn.itcats.UserFactory”></bean>
函數注入
(3)p名稱空間注入———實際上set注入,spring特有,為了簡化<property>寫法
1、applicationContext.xml中<beans>標簽頭部導入p命名空間
xmlns:p="http://www.springframework.org/schema/p"
2、書寫格式:值類型注入—— p:屬性名="值" 引用類型注入—— p:屬性名-ref="引用的<bean> name屬性"
把Run類中的name屬性值設置為haha,age屬性設置為20,引用屬性hello引用<bean name="hello" class="..."></bean>
<bean name="run2" class="cn.itcats.thread.Run" p:name="haha" p:age="20" p:hello-ref="hello"></bean>
(4)spel注入: spring Expression Language spring表達式語言
<bean name="runSpel" class="cn.itcats.thread.Run"> <!-- 取bean標簽中name為"user"中property為"name"中的value值 --!> <property name="name" value="#{user.name}"></property></bean>
SpEL特性:(1)、使用Bean的ID來引用Bean;(2)、調用方法和訪問對象的屬性;(3)、對值進行算術、關系和邏輯運算;(4)、正則表達式匹配;(5)、集合操作
關于spel https://www.cnblogs.com/goodcheap/p/6490896.html
復雜類型注入
1、需要導入包spring-web
2、在web.xml中配置監聽器
注意:假如不寫括號內的值(即name或id),默認使用類名首字母小寫作為搜索,為什么意思呢?
比如Student類中使用了@Component 沒有書寫括號和值,那么默認搜索id或name為student。
聲明Student類對象為多例 下面是對singleton和prototype的一些補充
singleton作用域:當把一個Bean定義設置為singleton作用域是,Spring IoC容器中只會存在一個共享的Bean實例,并且所有對Bean的請求,只要id與該Bean定義相匹配,則只會返回該Bean的同一實例。值得強調的是singleton作用域是Spring中的缺省作用域。
prototype作用域:prototype作用域的Bean會導致在每次對該Bean請求(將其注入到另一個Bean中,或者以程序的方式調用容器的getBean()方法)時都會創建一個新的Bean實例。根據經驗,對有狀態的Bean應使用prototype作用域,而對無狀態的Bean則應該使用singleton作用域。對于具有prototype作用域的Bean,有一點很重要,即Spring不能對該Bean的整個生命周期負責。具有prototype作用域的Bean創建后交由調用者負責銷毀對象回收資源。簡單的說:
singleton 只有一個實例,也即是單例模式。
prototype訪問一次創建一個實例,相當于new。
實際通過反射field賦值
實際通過set方式賦值
面試題: @AutoWired和@Resource的區別?
@AutoWired默認以類型進行查找,@Resource默認以名稱進行查找
@AutoWired(required=false) + @Qualifier("user") == @Resource(name="user")
其中@Resource注解是jdk1.6后才有的
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
JoinPoint(連接點):目標對象中,所有可以增強的方法,就是spring允許你是通知(Advice)的地方,那可就真多了,基本每個方法的前、后(兩者都有也行),或拋出異常是時都可以是連接點,spring只支持方法連接點。
Pointcut(切入點):目標對象中,已經被增強的方法。調用這幾個方法之前、之后或者拋出異常時干點什么,那么就用切入點來定義這幾個方法。
Advice(通知/增強) :增強方法的代碼、想要的功能。
Target(目標對象):被代理對象,被通知的對象,被增強的類對象。
Weaving(植入):將通知應用到連接點形成切入點的過程
Proxy(代理):將通知植入到目標對象之后形成的代理對象
aspect(切面):切入點+通知————通知(Advice)說明了干什么的內容(即方法體代碼)和什么時候干(什么時候通過方法名中的before,after,around等就能知道),二切入點說明了在哪干(指定到底是哪個方法),切點表達式等定義。
雖然現在都用Maven項目構建,但是不能忘記,使用aop需要用到的包:spring-aop + spring-aspects + springsource.org.aopalliance + springsource.org.aspectj.weaver
關于AOP看一個小例子:
1、準備目標對象(被代理對象,被通知的對象,被增強的類對象)
2、準備通知(被增強方法的代碼,想要實現功能的方法代碼)
3、配置 applicationContext.xml
1.導入aop(約束)命名空間
2.配置目標對象
3.配置通知對象
4.配置將通知織入目標對象
4、測試
總結:通知的幾種類型
1.前置通知———目標方法運行之前調用
2.后置通知———目標方法運行之后調用(如果出現異常不調用)
3.環繞通知———目標方法之前和之后都調用
4.異常攔截通知———如果出現異常,就會調用
5.后置通知———目標方法運行之后調用(無論是否出現異常都會調用)
1、applicationContext.xml中配置目標對象,通知對象,開啟使用注解完成織入
2、@Aspect注解代表該類是個通知類,書寫切點表達式@Pointcut("execution(返回值 全類名.方法名(參數))")
注意環繞通知需要這么寫:
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { //環繞方法執行前 //proceedingJoinPoint.proceed();表示對攔截的方法進行放行 //若注釋proceedingJoinPoint.proceed()則不會執行被AOP匹配的方法 proceedingJoinPoint.proceed(); //環繞方法執行后 }
AOP注解解析:
@Before 前置通知(Before advice) :在某連接點(JoinPoint)——核心代碼(類或者方法)之前執行的通知,但這個通知不能阻止連接點前的執行。為啥不能阻止線程進入核心代碼呢?因為@Before注解的方法入參不能傳ProceedingJoinPoint,而只能傳入JoinPoint。要知道從aop走到核心代碼就是通過調用ProceedingJionPoint的proceed()方法。而JoinPoint沒有這個方法。
這里牽扯區別這兩個類:Proceedingjoinpoint 繼承了 JoinPoint 。是在JoinPoint的基礎上暴露出 proceed 這個方法。proceed很重要,這個是aop代理鏈執行的方法。暴露出這個方法,就能支持 aop:around 這種切面(而其他的幾種切面只需要用到JoinPoint,這跟切面類型有關), 能決定是否走代理鏈還是走自己攔截的其他邏輯。建議看一下 JdkDynamicAopProxy的invoke方法,了解一下代理鏈的執行原理。這樣你就能明白 proceed方法的重要性。@After 后通知(After advice) :當某連接點退出的時候執行的通知(不論是正常返回還是異常退出)。
@AfterReturning 返回后通知(After return advice) :在某連接點正常完成后執行的通知,不包括拋出異常的情況。
@Around 環繞通知(Around advice) :包圍一個連接點的通知,類似Web中Servlet規范中的Filter的doFilter方法。可以在方法的調用前后完成自定義的行為,也可以選擇不執行。這是aop的最重要的,最常用的注解。用這個注解的方法入參傳的是ProceedingJionPoint pjp,可以決定當前線程能否進入核心方法中——通過調用pjp.proceed();
@AfterThrowing 拋出異常后通知(After throwing advice) : 在方法拋出異常退出時執行的通知。
spring中提供了一個可以操作數據庫的對象,對象封裝了jdbc技術 ————JDBCTemplate JDBC模板對象,而JdbcDaoSupport則對JdbcTemplate進行了封裝,所以要操作JdbcTemplate,或只需要繼承JdbcDaoSupport即可。
依賴關系配置:
測試:
事物的概述⑴ 原子性(Atomicity)
原子性是指事務包含的所有操作要么全部成功,要么全部失敗回滾,因此事務的操作如果成功就必須要完全應用到數據庫,如果操作失敗則不能對數據庫有任何影響。
⑵ 一致性(Consistency)
一致性是指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之后都必須處于一致性狀態。
拿轉賬來說,假設用戶A和用戶B兩者的錢加起來一共是5000,那么不管A和B之間如何轉賬,轉幾次賬,事務結束后兩個用戶的錢相加起來應該還得是5000,這就是事務的一致性。
⑶ 隔離性(Isolation)
隔離性是當多個用戶并發訪問數據庫時,比如操作同一張表時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個并發事務之間要相互隔離。
即要達到這么一種效果:對于任意兩個并發的事務T1和T2,在事務T1看來,T2要么在T1開始之前就已經結束,要么在T1結束之后才開始,這樣每個事務都感覺不到有其他事務在并發地執行。
關于事務的隔離性數據庫提供了多種隔離級別,稍后會介紹到。
⑷ 持久性(Durability)
持久性是指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的,即便是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。
例如我們在使用JDBC操作數據庫時,在提交事務方法后,提示用戶事務操作完成,當我們程序執行完成直到看到提示后,就可以認定事務以及正確提交,即使這時候數據庫出現了問題,也必須要將我們的事務完全執行完成,否則就會造成我們看到提示事務處理完畢,但是數據庫因為故障而沒有執行事務的重大錯誤。
關于事務的隔離級別我之前發布了一篇文章:https://blog.csdn.net/itcats_cn/article/details/81487466
spring中事務可以分為編程式事務控制和聲明式事務控制。
編程式事務控制
自己手動控制事務,就叫做編程式事務控制。
Jdbc代碼:
Conn.setAutoCommit(false); // 設置手動控制事務
Hibernate代碼:
Session.beginTransaction(); // 開啟一個事務
【細粒度的事務控制: 可以對指定的方法、指定的方法的某幾行添加事務控制】
(比較靈活,但開發起來比較繁瑣: 每次都要開啟、提交、回滾.)
聲明式事務控制
Spring提供了對事務的管理, 這個就叫聲明式事務管理。
Spring提供了對事務控制的實現。用戶如果想用Spring的聲明式事務管理,只需要在配置文件中配置即可; 不想使用時直接移除配置。這個實現了對事務控制的最大程度的解耦。
Spring聲明式事務管理,核心實現就是基于Aop。
【粗粒度的事務控制: 只能給整個方法應用事務,不可以對方法的某幾行應用事務。】
(因為aop攔截的是方法。)
Spring聲明式事務管理器類:
Jdbc技術:DataSourceTransactionManager
Hibernate技術:HibernateTransactionManager
有一點需要注意的:若為編程式事務控制,則開啟事務后一定要手動釋放(提交或回滾),否則長期占用內存,有可能報事務異常
spring封裝了事務管理的代碼(打開,提交,回滾事務)
事務操作對象,因為在不同平臺,操作事務的代碼各不相同.spring提供了一個接口
————— PlatformTransactionManager 接口
————— 在不同平臺,實現不同的接口即可
————— 注意:在spring中玩事務管理.最為核心的對象就是TransactionManager對象
spring管理事務的屬性介紹
(1)事務的隔離級別
(2)是否只讀
(3)事務的傳播行為
配置事務的核心管理器,它封裝了所有事務,依賴于連接池(DataSourceTransactionManager)
xml中配置通知
配置將通知織入目標
在需要管理的方法或者類中聲明配置事務管理
@Transactional(isolation=Isolation.REPEATABLE_READ,readOnly=false,propagation=Propagation.REQUIRED)
小編整理了一份Java基礎視頻、技術文檔、電子書、面試題、簡歷模板等福利分享給大家。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。