總覽:https://www.processon.com/view/link/605b14ab5653bb2225e6b0c5
一、Spring
1、概述
1、spring框架簡介
? 為簡化企業級開發而生,有效的降低代碼的耦合度,極大的方便專案的后期維護、升級和擴展,

2、優點
? 輕量、AOP支持、支持對各種框架的集成
3、體系結構
1、資料訪問
2、Web開發
3、AOP
4、集成訊息等
5、核心容器 IOC


2、IOC控制反轉
? ioc(Inversion of Control)是一種設計思想,把物件的創建、賦值、管理作業都交給代碼之外的容器實作,也就是物件的創建是有其他外部資源完成,
控制:創建物件,物件賦值,物件之間的關系管理
反轉:把原來開發人員管理、創建物件的權限轉交給代碼之外的容器實作,由容器代替開發人員管理物件,創建、賦值等
正轉:由開發人員在代碼中,使用new構造方法創建物件,開發人員主動管理物件‘;
容器:是一個服務器軟體(Tomcat),一個框架(spring)等
目的:
減少對代碼的改動,也能實作不同的功能,實作解耦合
所以:java中創建物件的方式:
1、new
2、反射,class的newInstance()方法,constructor的newInstance()方法
3、反序列化
4、克隆
5、ioc
ioc的技術實作:
? DI 是 ioc 的技術實作
? DI (Dependency Injection)依賴注入:只需要在程式中提供使用的物件名稱就可以,至于物件如何在容器中創建、賦值、查找都由容器內部實作,
spring是使用的 DI 實作了 ioc 的功能,spring底層創建物件,使用的是反射機制,
2.1 由spring創建物件
實作步驟:
-
創建maven專案
-
加入maven依賴
? spring依賴、junit依賴
-
創建類(介面和他的實作類)
? 和沒有使用框架一樣,就是普通類
-
創建spring需要使用的組態檔
? 宣告類的資訊,由spring創建和管理

僅限于初學的寫法:

2.2 DI(依賴注入)的實作方式:
1、基于xml組態檔:在Spring組態檔中,使用標簽和屬性完成
2、基于注解的實作:使用spring中的注解,完成屬性賦值
2.2.1 基于xml組態檔
? 適合經常需要修改
DI的語法分類:
1、 注入(set設值, 注入就是賦值):spring呼叫類的set方法,在set方法中實作屬性的賦值(最常用)
2、構造注入,spring呼叫類的有參構造方法,創建物件,在構造方法中完成賦值
set注入:
- 簡單型別的set注入:

property設值時name屬性必須在相應的類中有set方法,且有set方法沒有相應的變數也不會報錯
? 2.參考型別的set注入:

? 參考型別的自動注入:
? 1、byName:java類中參考型別的屬性名和spring容器中(組態檔)
<bean id="xx" autowire="byName"></bean>
讓Student類中所有的參考型別都按照byName規則完成賦值


? 2、byType(按型別注入):java類中參考型別的資料型別和spring容器中(組態檔)
? 同源:1、java類中參考型別的資料型別和bean中的class值一樣
? 2、java類中參考型別的資料型別和bean中的class值父子類關系的
? 3、java類中參考型別的資料型別和bean中的class值介面和實作類關系的
? 注:只能有一個符合條件的,多個會報錯
? class是Student類中參考的School的值:

構造注入
name屬性實作構造注入

index屬性實作
可以省略index=“”,但是必須按照引數的定義順序書寫

多組態檔優勢:
-
每個檔案的大小比一個檔案小很多,效率高
-
避免多人競爭帶來的沖突
按檔案的分配方式:
-
按功能模塊,一個模塊一個組態檔
-
按類的功能,資料庫相關的配置一個組態檔,做事務的功能一個組態檔,做service功能的一個組態檔

2.2.2 基于注解的實作
? 快捷,方便,適合不經常修改的
實作步驟:
-
加入maven依賴spring-context(間接加入了spring-aop依賴)
-
創建類,在類中加入spring 注解@Component(value=https://www.cnblogs.com/william-m/p/“xxx”),省略value=也可以(常用),如果只寫@Component則會默認value=首字母小寫的類名

還有 @Repository(用在持久層):放在dao的實作類,表示創建dao物件,dao物件是能訪問資料庫的 @Service(用在業務層):service物件是做業務處理,可以有事務等功能的 @Controller(用在控制器上):放在控制器(處理器)類的上面,創建控制器對象的,控制器物件能夠接受用戶提交的引數,顯示請求的處理結果 以上三個適用語法和@Component一樣,都能創建物件,但是他們三個還有額外的功能參考型別-@Autowired

參考型別@Resource

?
-
在spring組態檔中,加入一個組件掃描器的標簽,說明注解在專案中的位置

需要指定多個包時:


3、AOP面向切面編程
3.1 動態代理
? 動態代理能創建物件,在原有類代碼不變的情況下,實作功能的增加,功能增強,
3.1.1 JDK 動態代理
? 要求目標物件必須實作介面,java語言通過java.lang.reflect包提供三個類支持代理模式Proxy,Method和InvcationHandler,要求目標類和方法不能是final的,因為final不能被繼承,不能被重寫啊
? 實作步驟:
-
創建目標類,SomeserviceImpl目標類,給它的doSome,dother增加輸出時間,事務,
-
創建InvocationHandler介面的實作類,在這個類實作給目標方法增加功能,

-
使用jdk中類Proxy ,創建代理物件,實作創建物件的能力,

作用:
-
在目標類原始碼不改變的情況下,增加功能
-
減少代碼的重復
-
專注業務代碼邏輯
-
解耦合,讓業務與日志扥,事務非業務功能分離
3.1.2 CGLB動態代理(了解)
? CDLIB(Code Generation Library)是一個開源專案,原理是生成目標類的子類,子類是代理物件,
3.2 AOP簡介
? AOP(Aspect Orient Programming) 面向切面編程,底層的實作就是采用動態代理模式實作的,采用了JDK的動態代理和CGLIB的動態代理,
? Aspect:切面,給目標類增加的功能
? 特點:一般都是非業務方法,獨立使用的
如何理解AOP:
? 以切面為核心,圍繞切面來開發程式:
? 1)分析專案功能時找到切面
? 2)合理安排執行時間,(在目標方法前還是后)
? 3)合理的安排切面執行的位置, 在哪個類,哪個方法增加增強功能
3.3 AOP編程術語
-
AOP:切面,表示增強的功能,就是一堆代碼,完成某一個功能,非業務功能
? 常見的切面功能有日志,事務,統計資訊,引數檢查,權限驗證
-
JoinPoint:連接點,連接業務方法和切面的位置,就是某類中的業務方法
-
PointCut:切入點,指多個連接方法的集合,多個方法
-
目標物件:給哪個類的方法這個價功能,這個類就是目標物件
-
Advice:通知,表示切面功能 執行的時間,方法之前還是之后
切面三個關鍵要素:
- 切面的功能代碼,切面干什么
- 切面的執行位置,使用PointCut表示切面執行的位置
- 切面的執行時間,使用Advice表示時間,在目標方法之前還是之后
3.4 AOP的實作
? AOP是一個規范,是動態的一個規范化,一個標準
? aop的技術實作框架:
-
spring:spring內部實作了aop的規范,能做aop的作業
? spring在處理事務時使用aop
? 在專案開發中很少使用spring的aop實作,因為spring的aop比較笨重
-
Aspect:一個開源的專門做aop的框架,spring框架中集成了aspectj框架,通過spring就能使用aspectj的功能
aspectj框架實作aop的兩種方式:
- 使用xml的組態檔:配置全域事務
- 使用注解,在專案中要做aop功能,一般使用注解
3.4 AspectJ框架的使用
-
切面的執行時間,這個執行時間在規范中叫做Advice(通知,增強)
在aspect框架中使用注解表示,也可以使用xml組態檔中的標簽
<!-- 5個常用注解 @Before @AfterReturning @Around @After @AfterThrowing --> -
表示切面執行的位置,使用的是切入運算式
execution(訪問權限 方法回傳值 方法引數 例外型別)
在其中可以使用以下符號: * :0至多個任意字符 .. : 用在方法引數中,表示任意多個引數;用在包名后,表示當前包及其子包 + :用在類名后,表示當前類及其子類;用在介面名后,表示當前介面及其實作類指定切入點為:任意公共方法 execution(public * *(..)) 指定切入點為:任意一個以set開始的方法 execution(* set*(..)) 指定切入點為:com.mhz.service包中的任意類中的任意方法,不包含子包 execution(* com.mhz.service.*.*(..)) 指定切入點為:com.mhz.service或者子包包中的任意類中的任意方法 execution(* com.mhz.service..*.*(..)) 指定切入點為:所有service包下的任意類的任意方法 execution(* *..service.*.*(..))
使用aspectJ實作aop的基本步驟:
-
新建maven專案
-
加入依賴
- spring依賴
- aspectj依賴
- junit單元測驗(可有可無)
-
創建目標類:介面和他的實作類
要做的是給類中的方法增加功能
-
創建切面類:普通類
-
在類上加入注解@Aspect
-
定義方法,方法就是切面要執行的功能代碼
? 在方法上面加入aspectj中的注解,例如@Before,
? 有需要指定切入點運算式execution()
-
-
創建spring組態檔:宣告物件,把物件交給容器統一管理
? 宣告物件可以使用xml組態檔
或者注解 -
宣告目標物件
-
宣告切面類物件
-
宣告aspectj框架中的自動代理生成器標簽,
? 自動代理生成器:用來完成代理物件的自動創建功能的,
<!--把物件交給spring容器,由spring容器統―創建,管理物件--> <! --宣告目標物件--> <bean id="someservice" /> <! --宣告切面類物件--> <bean id="myAspect" 六個注解">六個注解:1、@Before:
前置通知注解 屬性: value,是切入點運算式,表示切面的功能執行的位置, 位置: 在方法的上面 特點: 1.在目標方法之前先執行的 2.不會改變目標方法的執行結果 3.不會影響目標方法的執行,
/* * 指定通知方法中的引數:JoinPoint * JoinPoint:業務方法,要加入切面功能的業務方法 * 作用是:可以在通知方法中獲取方法執行時的資訊,例如方法名稱,方法的實參, * 如果你的切面 功能中需要用到方法的資訊,就加入JoinPoint. * 這個JoinPoint引數的值是由框架賦予,必須是第一個位置的引數 */ @Before(value = "https://www.cnblogs.com/william-m/p/execution(void *..SomeServiceImpl.doSome(String, Integer))") public void myBefore(JoinPoint jp){ //獲取方法的完整定義 system.out.println("方法的簽名(定義)="+jp.getsignature()); system.out.println("方法的名稱="+jp.getsignature().getName());//獲取方法的實參 object args []= jp.getArgs(); for (object arg:args){ system.out.println("引數="+arg); } }2、@AfterReturning:
后置通知定義方法,方法是實作切面功能的, 方法的定義要求: 1.公共方法 public 2.方法沒有回傳值 3.方法名稱自定義 4.方法有引數的,推薦是object,引數名自定義 @AfterReturning:后置通知 屬性: 1.value切入點運算式 2.returning自定義的變數,表示目標方法的回傳值的,自定義變數名必須和通知方法的形參名一樣, 位置:在方法定義的上面 特點: 1. 在目標方法之后執行的, 2. 能夠獲取到目標方法的回傳值,可以根據這個回傳值做不同的處理功能 3. 可以修改這個回傳值@AfterReturning(value="https://www.cnblogs.com/william-m/p/execution(* *..SomeServiceImpl.doOther(..))",returning="res") // 此處returning的res名稱=Object的res名稱就行 public void myAfterReturing(object res){ // object res:是目標方法執行后的回傳值,根據回傳值做你的切面的功能處理 // 思考:如果是對類物件res的更改會不會影響在程式執行后得到的輸出結果? system.out.println("后置通知:在目標方法之后執行的,獲取的回傳值是:"+res); if(res.equals("abcd")) { //做―些功能 } e1se { //做其它功能 } }3、@Around
環繞通知 方法的定義格式: 1.public 2.必須有一個回傳值,推薦使用object 3.方法名稱自定義 4.方法有引數,固定的引數ProceedingjoinPoint@Around:環繞通知 屬性:value切入點運算式位宣:在方法的定義什么 特點: 1.它是功能最強的通知 2.在目標方法的前和后都能增強功能, 3.控制目標方法是否被呼叫執行 4.修改原來的目標方法的執行結果,影響最后的呼叫結果 等同于jdk動態代理的,InvocationHandler介面 引數:ProceedingJoinPoint 等同于Method 作用:執行目標方法 回傳值:就是目標方法的執行結果,可以被修改@Around(value = "https://www.cnblogs.com/william-m/p/execution(* *..SomeService1mpl.doFirst(..))") public object myAround(ProceedingJoinPoint pjp) throws Throwable { // 獲取第一個引數值 Object[] args = pjp.getArgs(); String name = ""; if(args != null && args.length > 1){ Object arg = args[0]; name = (String)arg; } //實作環繞通知 object result = null; system.out.println("環繞通知:在目標方法之前,輸出時間:"+ new Date()); //1.目標方法呼叫 if("xxx".equals(name)){ // 控制是否執行目標方法 result = pjp.proceed(); //method.invoke(); object result = doFirst(); } system.out.println("環繞通知:在目標方法之后,提交事務"); //2.在目標方法的前或者后加入功能 //回傳目標方法的執行結果 return result; }4、 @AfterThrowing
例外通知: 1、public 2、沒有回傳值 3、方法,名稱自定義 4、方法有一個Exception,如果還有就是JoinPoint@AfterThrowing:例外通知 屬性:1、value 2、throwing自定義變數,表示目標方法拋出的例外物件,變數名和方法的引數名一樣 特點:1、在目標方法拋出例外時執行 2、可以做例外的監控程式,如果有例外,可以發郵件,短信通知等 執行時: 沒有例外就走正常邏輯,有例外就走定義的@AfterThrowing注解的方法 try{ SomeServiceImpl.doSecond(..); } catch(Exception ex){ myAfterThrowing(ex); }@AfterThrowing(value = "https://www.cnblogs.com/william-m/p/execution(* *..SomeServiceImpl.doSecond(..))",throwing = "ex") public void myAfterThrowing(Exception ex){ system.out.println("例外通知:方法發生例外時,執行: "+ex.getMessage());//發送郵件,短信,通知開發人員 }5、@ After
最終通知 方法的定義格式 1.public 2.沒有回傳值 3.方法名稱自定義 4.方法沒有引數,如果還有是JoinPoint@After:最終通知 屬性:value 切入點運算式 位置:方法上面 特點: 1、總是執行 2、目標方法后執行,即使拋出了例外 類似于: try/catch中的finally代碼塊@After(value = "https://www.cnblogs.com/william-m/p/execution(* *..SomeserviceImpl.doThird(..))") public loidmyAfter(){ //一般做資源清除作業的, systemyout.println("執行最終通知,總是會被執行的代碼"); }6、 @PointCut
定義管理切入點 如果專案中很多個切入點運算式是重復的,,使用@PointCut 屬性:value 切入點運算式 位置:方法上面 特點: 當使用@Pointcut定義在一個方法的上面,此時這個方法的名稱就是切入點運算式的別名,其它的通知中,value屬性就可以使用這個方法名稱,代替切入點運算式了@Pointcut(value = "https://www.cnblogs.com/william-m/p/execution(* *..SomeserviceImpl.doThird(..))”) private void mypt(){ //無需代碼, } // 然后: @Before(value="mypt()") public void myBefore(){ }4、Spring事務
4.1 Spring的事務管理
-
什么是事務?
? 指的是一組sql陳述句的集合,集合中有多個sql陳述句,增刪查改,希望這些sql陳述句斗毆成功或者都失敗,這些sql 的執行是一致的,作為一個整體執行,
-
什么時候用到事務?
? 當操作涉及多個表或者多個sql陳述句的增刪改,需要保證這些sql陳述句都成功才能完成功能,或者都失敗,保證操作是符合要求的,
? 在java代碼中寫程式,控制事務,需要寫在service類的業務方法上,因為業務方法匯呼叫多個dao方法,執行多個sql陳述句
-
jdbc、Mybatis訪問資料庫處理事務?
//jdbc Connection conn; conn.commit(); conn.rollback(); //mybatis SqlSession.commit(); SqlSession.rollback(); -
問3中處理事務的方式是不同的,所以有哪些不足:
-
不同的資料庫訪問技術,處理事務的物件、方法不同,需要掌握了解不同資料庫訪問技術使用事務的原理
-
掌握多種資料庫中事務的處理邏輯,提交、回滾等
多種資料庫訪問技術,有不同的事務處理的機制,物件、方法
-
-
解決不足
? spring提供一種統一處理事務的統一模型,能使用統一步驟,方式完成多種不同資料庫訪問技術的事務處理,
? 使用spring的事務處理機制,可以完成mybatis、hibernate等訪問資料庫的事務處理,
-
處理事務,需要怎么做,做什么
spring處理事務的模型,使用的步驟都是固定的,把事務使用的資訊提供給spring就可以了-
事務內部提交,回滾事務,使用的事務管理器物件,代替你完成commit,rollback
事務管理器是一個介面和他的眾多實作類,
介面:PlatformTransactionManager ,定義了事務重要方法commit , rollback
實作類: spring把每一種資料庫訪問技術對應的事務處理類都創建好了,
mybatis訪問資料庫---spring創建好的是DatasourceTransactionManagerhibernate? 訪問資料庫----spring創建的是HibernateTransactionManager
怎么使用:你需要告訴spring 你用是那種資料庫的訪問技術,怎么告訴spring呢?
宣告資料庫訪問技術對于的事務管理器實作類,在spring的組態檔中使用宣告就可以了例如,你要使用mybatis訪問資料庫,你應該在xml組態檔中 <bean id="xxx" > -
業務方法需要什么樣的事務,說明需要事務的型別,
? 說明方法需要的事務:
? 1)事務的隔離級別:
? DEFAULT:采用 DB默認的事務隔離級別,Mysql的默認為REPEATABLE_READ;Oracle默認為 READ_COMITTED.READ
? UNCOMMITTED:讀未提交,未解決任何并發問題,
? READ_COMMITTED:讀已提交,解決臟讀,存在不可重復讀與幻讀,? REPEATABLE_READ:可重復讀,解決臟讀、不可重復讀,存在幻讀SERIALIZABLE:串行化,不存在并發問題,
? 2)事務的超時時間:表示一個方法的最長執行時間,如果方法執行超過了時間,事務就回滾
? 3)事務的傳播行為:控制業務方法是不是有事務的,是什么樣的事務
? 7個傳播行為,表示業務方法呼叫時,事務在方法之間是如何使用的
?
<!--!!! PROPAGATION REQUIRED PROPAGATION_REQUIRES_NEW PROPAGATIONsUPPORTS --> PROPAGATIONMANDATORY PROPAGATION_NESTED PROPAGATION_NEVER PROPAGATIONNOT_SUPPORTED -
事務提交事務,回滾事務的時機
1)當你的業務方法,執行成功,沒有例外拋出,當方法執行完畢,spring在方法執行后提交事務,事務管理器commit2)當你的業務方法拋出運行時例外或ERROR,spring執行回滾,呼叫事務管理器的rollback
運行時例外的定義: RuntimeException 和他的子類都是運行時例外,例如Ntul1PointException , MunberFormatzxcept.
3)當你的業務方法拋出非運行時例外,主要是受查例外時,提交事務
受查例外:在你寫代碼中,必須處理的例外,例如IOException,SQLException
-
總結Spring事務:
- 管理事務的是 事務管理 和他的實作類
- spring的事務是一個統一模型
- 指定使用的事務管理器的實作類,使用
- 指定哪些類,哪些方法需要加入事務的功能
- 指定方法需要的隔離級別,傳播行為,超時
- 指定使用的事務管理器的實作類,使用
4.2 Spring的事務傳播機制
**Required **解義:如果背景關系中已經存在事務,就加入到事務當中
背景關系有事務 背景關系沒有事務 Required 加入到事務當中 新建事務 Supports 加入到事務當中 非事務方式運行 Mandatory 必須要有事務 拋出例外 Requires_New 新建事務 新建事務 Not_Supported 事務掛起,方法結束后恢復事務 Never 拋出runtime例外,強制停止執行 Nested 嵌套事務執行 新建事務 二、SpringMVC
1.1 MVC在B/S下的應用
mvc是一個設計模式

1.2 springmvc框架

程序
1、發起請求到前端控制器
2、前端控制器請求HandlerMapping查找Handler
? 根據xml配置、注解進行查找
3、處理器映射器HandlerMapping向前端控制器回傳Handler
4、前端控制器用處理器配接器去執行Handler
5、理器配接器執行Handler
6、Handler執行完成給配接器回傳ModelAndView
7、處理器向前端控制器回傳ModelAndView
? ModelAndView是springmvc框架的一個底層物件,包括model 和 view
8、前端控制器請求視圖決議器去進行視圖決議
? 根據邏輯視圖名決議程真正的視圖jsp
9、視圖決議器向前端控制器回傳View
10、前端控制器進行視圖渲染
? 視圖渲染將模型資料(在ModelAndView中)填充到request域
11、前端控制器向用戶回傳回應結果
組件:
1、前端控制器DispatcherServlet,(不需要程式員開發)
? 接收請求,回應結果,相當于轉發器,中央處理器
? 減少其他組件之間的耦合度
2、處理器映射器HandlerMapping,(不需要程式員開發)
? 根據請求的url查找Handler
3、處理器配接器HandlerAdapter(不需要程式員開發)
? 按照特定規則(HandlerAdapter要求的規則)去執行Handler
? 撰寫Handler時按照HandlerAdapter的要求去做才能正確執行Handler
4、處理器Handler,(需要程式員開發)
5、視圖決議器View Resolver
? 視圖決議,根據邏輯視圖域名決議成真正的視圖View
6、視圖View,(需要程式員開發jsp)
? 是一個介面,實作類支持不同的View型別(jsp、freemarker、pdf...)
2、 json資料互動
2.1、使用json互動的原因:
? json資料格式在介面呼叫中、html頁面中常用,json格式簡單,決議比較方便
2.2、springmvc進行json互動
springmvc中使用jackson的jar包進行json轉換
客戶端請求key / value串 請求的是json串
contenttype=application/json請求的是key / value
contenttype=@RequestBody將json串轉成java物件 不需要@RequestBody將json串轉成java物件 @ResponseBody將java物件轉成json輸出 @ResponseBody將java物件轉成json輸出 最后都輸出json資料,為了在前端頁面方便對請求結果進行決議 1、請求json、輸出json,要求請求的是json串,所以在前端頁面中需要將請求的內容轉成json,不太方便


2、請求key / value ,輸出json,比較常用


3、Restful支持
restful是一種開發理念,是對http的一個詮釋,即表現層狀態的轉化
對url進行規范,寫restful格式的url,就是簡潔
非rest的url:http://.../finditems.action?id=001
rest的url風格:http://.../items/001
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/440358.html標籤:Java
-
