SpringAOP動態代理小結

學習springAOP時,順便學習了jdk與cglb動態代理,jdk與cglb動態代理最大不同之處就是jdk動態代理是基於接口的,如果有的項目不是基於接口又想實現動態代理,就需要cglb動態代理,這裏總結下AOP的動態代理。
springAOP動態代理實現方式
是基於jdk與cglb的,就是選它們一種來實現。這裏涉及兩個屬性

proxyTargetClass屬性,若爲true,則是面向類動態代理,這時是基於CGLB,需要CGLB包cglib-nodep-2.1_3.jar
或者設置optimize爲true。就是基於CGLB包的,springAOP默認是基於JDK動態代理,就是需要接口

springAOP的五種增強
要實現增強需寫一個類實現這幾個方法

前置增強:org.springframework.aop.BeforeAdvice 
後置增強:org.springframework.aop.AfterAdvice 
環繞增強:org.springframework.aop.MethodInterceptor
異常拋出增強: org.springframework.aop.ThrowsAdvice
引介增強:org.springframework.aop.IntroductionInterceptor 
重點總結下引介增強:針對類(對象),改變對象中的某個屬性或方法的時候執行通知類型
具體繼承類:DelegatingIntroductionInterceptor(已實現上面的接口)

寫一個例子來分析引介增強

//這裏我用的基於cglib代理的,所以不定義接口
//定義一個目標類,保存什麼東西。我想在保存的時候在前面做一些事,或者後面做一些事,並且可以控制我是否可以做這些事,不想做就取消,想做就添加,這是環繞通知做不到的。
public class Waiter {

    public void save(String name){
        System.out.println("保存=============" + name);
    }
}
//寫個接口,控制我是否啓動來做這些事比如數據庫事物的開啓與關閉
public interface IControllerOpen {
    //控制通知的打開和關閉
    public void setOpen(boolean flag);
}
//織入類,繼承DelegatingIntroductionInterceptor這個類並實現我們的控制接口
public class ControllerInterceptor extends DelegatingIntroductionInterceptor implements IControllerOpen{
    ThreadLocal<Boolean> threadLocal = new ThreadLocal<Boolean>();
    //名字必須一樣,因爲這是最初接口的名字,我們只是再繼承了一個類
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable{
        Object obj = null;
        if(threadLocal.get() != null && threadLocal.get()){     
            System.out.println("事物開啓。。。");
            obj = super.invoke(mi);
            System.out.println("事物提交。。。。");
        }else{
            obj = super.invoke(mi);
        }
        return obj;
    }
    @Override
    public void setOpen(boolean flag) {
        threadLocal.set(flag);
    }

}
//歐了,寫個測試
public class Test {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:com/tree/aop3/bean.xml");
        Waiter waiter = (Waiter) context.getBean("proxy");
        IControllerOpen contro = (IControllerOpen) waiter;
        //設置爲false,表示我不想增強了,如果設置或true則表示增強,方便控制了
        contro.setOpen(false);
        waiter.save("黑貓");
        System.out.println("============");
    }
}
//當然還有ioc的配置
     <!-- 目標類(對象) -->
    <bean id="target" class="com.tree.aop3.Waiter"></bean>
    <!-- 織入類 -->
    <bean id="advice" class="com.tree.aop3.ControllerInterceptor"></bean>
    <!-- 代理工廠 -->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="target"></property>
        <property name="interfaces" value="com.tree.aop3.IControllerOpen"></property>
        <property name="interceptorNames" value="advice"></property>
        <property name="proxyTargetClass" value="true"></property>
    </bean>

其餘的增強都大同小異,不過異常增強通知是需要手動拋出一個異常的。歐了,小長我繼續學習去了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章