1. 程式人生 > 其它 >spring -7 aop程式設計

spring -7 aop程式設計

技術標籤:筆記javaaopspring

目錄

aop程式設計

1,為什麼需要代理設計模式?

2,現實生活中代理的解決方案--租房。

3,靜態代理存在的問題

4,解決方案-spring動態代理開發。

代理三要素:原始物件,額外功能,組裝。

5,spring動態代理編碼。

6,細節補充


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>