Spring學習筆記(二)
- 1.AOP
-
- 1.1 AOP的基本概念
- 1.2 AOP底層原理
- 1.3 JDK動态代理
- 1.4 術語
- 1.5 準備工作
- 1.6 基于AspectJ注解的方式
- 2.事務
-
- 2.1 事務概念
1.AOP
1.1 AOP的基本概念
- AOP:面向切面程式設計,利用AOP可以對業務邏輯的各個部分進行隔離,進而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。
- 通俗描述:不通過修改源代碼方式,在主幹功能中添加新的功能
- 場景引入
1.2 AOP底層原理
-
AOP底層使用動态代理
(1)動态代理有兩種情況:
①有接口,使用JDK動态代理
建立接口的代理對象,增強類的方法
②沒有接口,使用CGLIB動态代理 ③差別:JDK建立實作類代理對象,CGLIB建立子類代理對象
1.3 JDK動态代理
- JDK的動态代理,使用Proxy類裡面的方法建立出代理對象 (1)調用newProxyInstance方法
第一個參數:ClassLoader類加載器
第二個參數:增強方法所在的類所實作的接口,支援多個接口
第三個參數:實作InvocationHandler接口,建立代理對象,寫增強的方法
-
代碼實作
(1)建立接口,定義方法
public interface UserDao {
public int add(int a,int b);
public String update(String id);
}
(2)建立接口實作類,實作方法
public class UserDaoImpl implements UserDao {
@Override
public int add(int a, int b) {
return a+b;
}
@Override
public String update(String id) {
return id;
}
}
(3)使用Proxy類建立接口的代理對象
public class JDKProxy {
public static void main(String[] args) {
Class[] interfaces = {UserDao.class};
UserDaoImpl userDao = new UserDaoImpl();
UserDao dao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDao));
int result = dao.add(1,2);
System.out.println(result);
}
}
//建立代理對象的代碼
class UserDaoProxy implements InvocationHandler{
//建立哪個實作類的代理對象,需要傳入該實作類
private Object obj;
public UserDaoProxy(Object obj){
this.obj = obj;
}
//增強的邏輯
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法之前
System.out.println("增強方法之前被執行了..." + method.getName() + "傳遞的參數:" + Arrays.toString(args));
//執行方法
Object res = method.invoke(obj, args);
//方法之後
System.out.println("增強方法之後執行...");
return res;
}
①InvocationHandler接口,可以使用匿名内部類的方式傳遞,也可以編寫一個實作類傳遞。
②編寫InvocationHandler實作類,需要傳入需要增強的類。
③代理後會傳回一個新的實作類,需要接收。
1.4 術語
- 連接配接點:類裡面哪些方法可以被增強,這些方法稱為連接配接點
- 切入點:實際真正被增強的方法,成為切入點
-
通知(增強)
(1)實際增強的邏輯部分成為通知(增強)
(2)通知有多種類型:①前置通知 ②後置通知 ③環繞通知(在方法的前後都增強) ④異常通知(在發生異常時增強) ⑤最終通知 (類似finally,永遠會執行)
- 切面:把通知應用到切入點的過程,稱為切面,是一個動作
1.5 準備工作
-
Spring架構基于AspectJ實作AOP操作
AspectJ不是Spring組成部分,是獨立的AOP架構,一般把AspectJ和Spring架構一起使用,進行AOP操作
-
基于AspectJ實作AOP操作的兩種方式
(1)基于xml配置檔案實作
(2)基于注解方式實作
- AOP相關依賴檔案
-
切入點表達式
(1)切入點表達式:表示對類中的哪個方法進行增強
(2)文法結構
權限修飾符可省略
execution([權限修飾符][傳回類型][類全路徑][方法名稱](參數清單))
(3)示例
①對com.test.dao.BookDao類裡面的add方法進行增強
execution(* com.test.dao.BookDao.add(…))
②對com.test.dao.BookDao類中的所有方法進行增強
execution(* com.text.dao.BookDao.*(…))
③對com.test.dao包下的所有方法進行增強
execution(* com.test.dao.*(…))
1.6 基于AspectJ注解的方式
1、建立類,在類中定義方法
public class User {
public void add(){
System.out.println("add.......");
}
}
2、建立增強類,編寫增強邏輯
(1)在增強類中建立方法,讓不同方法代表不同的通知類型
public class UserProxy {
public void before(){
System.out.println("before.......");
}
}
3、進行aop相關配置
(1)在spring的配置檔案中,開啟注解掃描,開啟生成代理對象
<?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:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 開啟注解掃描 -->
<context:component-scan base-package="com.test.spring5"></context:component-scan>
<!-- 開啟AspectJ生成代理對象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
(2)使用注解建立被增強的類和增強類
(3)在增強類上添加注解@Aspect
4、配置不同類型的通知
(1)在增強類裡,作為通知方法上面添加通知類型注解,使用切入點表達式配置
@Component
@Aspect
public class UserProxy {
@Before(value="execution(* com.test.spring5.User.add())")
public void before(){
System.out.println("before.......");
}
@Around(value="execution(* com.test.spring5.User.add())")
public void around(ProceedingJoinPoint proceedingJoinPoint){
System.out.println("環繞之前.......");
proceedingJoinPoint.proceed();
System.out.println("環繞之後.......");
}
}
@Before 前置通知
@AfterReturning 後置通知 方法必須正确執行才會執行
@Around 環繞通知 參數ProceedingJoinPoint表示被增強的方法
@After 最終通知 無論方法是否正确運作都會執行,類似finally
@AfterThrowing 異常通知
優先級為Around→Before→After→AfterReturning→AfterThrowing
5、重用切入點的抽取
@PointCut(value="execution(* com.test.spring5.add())")
public void pointCut(){
}
@Before(value="pointCut()")
public void before(){
System.out.println("before......");
}
@PointCut标簽抽取切入點,value寫标記的方法名
6、有多個增強類,對同一個方法進行增強,設定增強類優先級。
(1)在增強類上添加注解@Order(數字類型值),值越小優先級越高
2.事務
2.1 事務概念
-
什麼是事務
(1)事務是資料庫操作最基本單元,邏輯上一組操作,要麼都成功,有一個失敗就全都失敗。
(2)典型場景:銀行轉賬
-
事務四大特性(ACID)
(1)原子性:要麼都成功,一個失敗都失敗
(2)一緻性:事務送出前後的資料完整性和狀态保持一緻
(3)隔離性:事務間是互相獨立的,不會互相影響
(4)持久性:事務送出後表中資料真正發生了變化