spring -7 aop程式設計
阿新 • • 發佈:2021-02-10
目錄
aop程式設計
1,為什麼需要代理設計模式?
在javaee分層開發中,service層對於我們來說很重要,該層包括了dao,事務操作,也就是核心業務,而有一些程式碼,比如說事務,日誌,效能(程式執行時間)程式碼量少,不屬於核心業務,可有可無。
站在呼叫者的角度,需要,站在設計者的角度(我實現功能就行了),不需要。
2,現實生活中代理的解決方案--租房。
房東:核心功能(籤合同,收房租);額外功能(放廣告,帶人看房);
房客:我需要房子住,但是我也需要實地看房。
中介:引入代理,代替房東去做一些它不想做的工作,比如說投放廣告,帶人看房,但是核心功能(籤合同,收房租),還是讓房東來。
3,靜態代理存在的問題
靜態檔案過多,不利於專案的管理。維護功能差,額外功能修改複雜(麻煩)。
4,解決方案-spring動態代理開發。
代理三要素:原始物件,額外功能,組裝。
spring的兩種方法(MethodBeforeAdvice介面和MethodInterceptor介面)。直接使用MethodInterceptor介面。
MethodInterceptor可以在原始方法執行之前,之後新增額外方法。而MethodBeforeAdvice只會在之前(不靈活)。
5,spring動態代理編碼。
spring動態代理四步: 目標物件(實現類),額外功能(MethodInterceptor),切入點(aop:pointcut),組裝(aop:advisor)
public class UserDaoImpl implements IUserDao{ @Override public void save(Person person) { System.out.println("dao save..."); } @Override public void query(String name) { System.out.println("dao query name "+ name); } }
<!-- 原始物件-->
<bean id="userDao" class="core.UserDaoImpl"></bean>
<!-- 額外功能-->
<bean id="around" class="aop.MyAspect"></bean>
<aop:config>
<!-- 定義切入點-->
<aop:pointcut id="pc" expression="execution(* query(..))"/>
<!-- 組裝-->
<aop:advisor advice-ref="around" pointcut-ref="pc"></aop:advisor>
</aop:config>
test程式碼
/**
* 測試:spring工廠得到代理物件
*/
@org.junit.Test
public void test5(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
IUserDao userDao = (IUserDao) ctx.getBean("userDao");
userDao.query("jackson");
}
結果:
備註:1,MethodInterceptor會影響原始方法的返回值,必須返回ret(原始方法執行結果)。
2,spring通過id獲得的是代理物件(詳情在spring -6補充中)
6,細節補充
在動態代理時,沒有看到代理類的存在,spring框架在執行時,class檔案在JVM內建立,執行在JVM內部,等待程式結束後,隨JVM一起消失。
spring預設使用JDK動態代理,springboot預設使用cglib。
<!--Proxy -target-class 預設false,執行JDK,true,執行cglib-->
<aop:config proxy-target-class="true">
<!-- 定義切入點-->
<aop:pointcut id="pc" expression="execution(* query(..))"/>
<!-- 組裝-->
<aop:advisor advice-ref="around" pointcut-ref="pc"></aop:advisor>
</aop:config>