441、排列硬幣(Arranging Coins)
阿新 • • 發佈:2021-01-21
技術標籤:spring框架設計模式java設計模式spring
1 代理模式的產生
-
額外功能
1. 軟體設計者的角度Service層不需要額外功能 2. Service層的呼叫者則需要額外功能 示例: 1. 房東(軟體設計者)出租房子,只想實現核心功能而不去實現額外功能 核心功能: 1.出租房屋 2.收錢 額外功能: 1.打廣告 2.帶客戶看方 2. 房客(軟體呼叫者)則需要這些額外功能。 此時房東和房客就會產生矛盾,應景而生中介(proxy)。房東不想實現的額外功能中介來實現
2 設計模式
2.1 概念
通過代理類,為原始類(目標類)增加額外的功能
2.2 好處
利於原始類的維護
2.3 示例場景
事務、日誌、效能檢測
2.4 核心要素
1. 原始類
2. 原始類實現的介面(代理類必須和原始類的方法保持一致,所以需要實現共同的介面)
3. 額外功能
3 靜態代理
3.1 編碼實現
3.2 存在問題
1. 每一個原始類都需要與之對應的代理類的實現,靜態類檔案數量過多,不利於專案管理
2. 額外功能難以維護,需要去修改每一個代理類的額外功能實現
4 動態代理
4.1 spring的動態代理
4.1.1 依賴jar包
org.springframework:spring-aop:5.1.14.RELEASE org.aspectj:aspectjrt:1.8.8 org.aspectj:aspectjewaver:1.8.3
4.1.2 實現額外功能
/**
* @author wl
* @version 1.0
* @Description 實現MethodBeforeAdvice介面重寫before方法,實現原始方法之前的額外功能
* @date 2021/1/20 19:36
*/
public class Before implements MethodBeforeAdvice {
/**
* @Description 需要把在原始方法執行之前執行的額外功能寫在before方法中
* @Param [method, objects, o]
* @return
*/
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("--- method before advice ----");
}
}
4.1.3 原始類、共同介面
// 共同介面
public interface UserService {
boolean login(String name, String password);
}
// 原始類
public class UserServiceImpl implements UserService {
@Override
public boolean login(String name, String password) {
return true;
}
}
4.1.4 定義切入點
切入點:額外功能加入的位置
<!-- spring的xml配置檔案中定義切入點-->
<aop:config>
<!-- 給所有方法加入額外功能 -->
<aop:pointcut id="ex" expression="execution(* *(..))"
</aop:config>
4.1.5 組裝
<!-- 將切入點和額外功能整合 -->
<aop:config>
<!-- 給所有方法加入額外功能 -->
<aop:pointcut id="ex" expression="execution(* *(..))"/>
<!-- 指定額外功能和切入點的id -->
<aop:advisor advice-ref="before" pointcut-ref="ex"/>
</aop:config>
4.1.6 呼叫
spring的工廠通過原始物件的id值獲得的是代理物件
<bean name="userService" class="UserServiceImpl"></bean>
所以 getBean("userService")獲得的是代理物件。
將獲取的代理物件進行儲存,可通過共同介面的型別宣告
UserService userService = (UserSerivce)applicationContext.getBean("userService");
4.2 spring動態代理細節
4.2.1 代理類存放位置
Spring框架在執行時,通過動態位元組碼技術,在JVM中建立的,代理類執行在JVM內部。生命週期和JVM一致
4.2.2 動態位元組碼
不存在靜態java檔案,也就無法編譯成class檔案。
動態位元組碼是通過第三方的動態位元組碼框架在JVM中建立。如:Cglib、ASM、Javassist
有了位元組碼就可在JVM中建立物件
4.2.3 動態代理好處
1. 不需要定義代理類檔案,都是JVM執行過程中動態建立。不會造成類檔案過程,而影響專案管理的問題。
2. 在額外功能不改變的情況下,只需要指定原始類,不再需要如靜態代理般自己定義代理檔案
3. 額外功能要改變的化,只需要重新實現Advice介面重新組裝,不再需要如靜態代理般每個代理都去修改
1. 不需要定義代理類檔案,都是JVM執行過程中動態建立。不會造成類檔案過程,而影響專案管理的問題。
2. 在額外功能不改變的情況下,只需要指定原始類,不再需要如靜態代理般自己定義代理檔案
3. 額外功能要改變的化,只需要重新實現Advice介面重新組裝,不再需要如靜態代理般每個代理都去修改