posts - 66,  comments - 11,  trackbacks - 0
              Spring的AOP框架允許你將分散在系統中的功能塊放到一個地方-切面。重用通用功能的常用面向對象技術是使用繼承和委

          托模式。但由于基礎類在系統中到處使用,使用繼承會引起脆弱的繼承關系。委托模式比較笨拙,依然需要重復調用委托對象

          。使用AOP,你也是在一個地方定義通用功能,只是你可以聲明式定義何時何地應用這些功能,而不一年歐冠在需要新功能的地

          方修改代碼。交叉業務現在可以被模塊化到特定對象切面中。這樣做有2個好處,第一,現在每個業務邏輯放在一個地方,而不

          是分散到代碼的各個角落。第二,我們的服務模塊現在更加清晰,因為他們只包含他們的核心功能,輔助功能轉移到切面中。

              切面(Aspect):切面是你要實現的交叉功能。切面最常用的例子是日志記錄。日志記錄在系統中到處需要用到。
              連接點(Joinpoint):連接點是應用程序執行過程中插入切面的地點。這個地點可以是方法調用,異常拋出,或者是要修改

          字段。切面代碼在這些地方插入到你的應用流程中,添加新的行為。
              通知(Advice):通知切面的實際實現。它通知應用系統新的行為。
              切入點(PointCut):切入點定義了通知應該應用在哪些連接點。通知可以應用到AOP框架支持的任何連接點。你并不希望把

          所有切面應用到所有可能的連接點上。切入點讓你指定通知應用到什么地方。
              引入(Introduction):引入允許你為已存在類添加新方法和屬性。
              目標對象(Target):目標對象是被通知對象。它既可以是你編寫的類也可以是你要添加定制行為的第三方類。
              代理(Proxy):代理是將通知應用到目標對象后創建的對象。對于客戶對象來說,目標對象和代理對象是一樣的。
              織入(Weaving):織入是將切面應用到目標對象從而創建一個新的代理對象的過程。
              切入點定義了哪些連接點要被通知。

              Spring的AOP實現:
              在Spring中所有的通知都以Java類的形式編寫。代理Bean只有在第一次被應用系統需要的時候才被創建。如果你使用的是ApplicationContext,代理對象在BeanFactory載入所有Bean的時候被創建。因為Spring在運行期創建代理,所以使用Spring AOP不需要特殊編譯期。
              Spring有2種代理創建方式。如果目標對象實現了一個接口暴露的方法,Spring將使用JDK的Java.lang.reflect.Proxy類創建代理。這個類讓Spring動態產生一個新的類,它實現了所需的接口,織入了通知,并且代理對目標對象的所有請求。
              如果目標對象沒有實現任何接口,Spring使用CGLIB庫生成目標對象的子類。在創建這個子類的時候,Spring將通知織入,并且對目標對象的調用委托給這個子類。

              通知包含了切面的邏輯。所以當你創建一個通知對象的時候,你是在編寫實現交叉功能的代碼。而且,記住Spring的連接點模型是建立在方法攔截上。這意味著你編寫的Spring通知會在方法調用周圍的各個地方織入系統中。通知的類型有:Around,Before,After,Throws

          前置通知:需要擴展MethodBeforeAdvice接口
          public interface MethodBeforeAdvice{
              void before(Method method,Object[] args,Object target)throws Throwable;
          }

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

          <beans>
              
          <!-- 創建代理目標對象 -->
              
          <bean id="kwikEMartTarget" class="com.springinaction.chapter03.store.ApuKwikEMart"></bean>
              
          <!-- 創建通知 -->
              
          <bean id="welcomeAdvice" class="com.springinaction.chapter03.store.WelcomeAdvice"></bean>
              
          <!-- 創建代理對象 -->
              
          <bean id="kwikEMart" class="org.springframework.aop.framework.ProxyFactoryBean">
                  
          <!-- 代理類實現的接口 -->
                  
          <property name="proxyInterfaces">
                      
          <value>com.springinaction.chaper03.store.kwikEMart</value>
                  
          </property>
                  
          <!-- 要織入的通知 -->
                  
          <property name="interceptorNames">
                      
          <list>
                          
          <value>welcomeAdvice</value>
                      
          </list>
                  
          </property>
                  
          <!-- 要代理的目標對象 -->
                  
          <property name="target">
                      
          <ref bean="kwikEMartTarget"/>
                  
          </property>
              
          </bean>
          </beans>

          ProxyFactoryBean類是一個在BeanFactory中顯示的創建代理對象的中心類。像我們展示的那樣,你可以給它一個要實現的接口,一個要代理的目標對象,一個要織入的通知,并且它將創建一個嶄新的代理對象。通常配置ProxyFactoryBean,讓它實現和目標對象一樣的接口。

          后置通知:需要實現AfterReturningAdvice
          public interface AfterReturningAdvice{
              void afterReturning(Object returnValue,Method method,Object[] args,Object target)throws Throwable;
          }

          環繞通知:需要實現MethodInterceptor,同時實現前置和后置通知
          public interface MethodInterceptor extends Interceptor{
              Object invoke(MethodInvocation invocation)throws Throwable;
          }
          MethodInterceptor接口和前面介紹的2種通知不同點:
          1、MethodInterceptor能夠控制目標方法是否真的被調用。通過調用MethodInvocation.proceed()方法來調用目標方法。這一點不同于前兩個,目標方法總是被調用的。
          2、MethodInterceptor讓你可以控制返回的對象。就是說你可以返回一個與proceed()方法返回對象完全不同的對象。
          package com.wyq.spring.base.aopinstance;

          import java.util.HashSet;
          import java.util.Set;

          import org.aopalliance.intercept.MethodInterceptor;
          import org.aopalliance.intercept.MethodInvocation;
          import org.jboss.remoting.samples.transporter.basic.Customer;


          /** 
           * 
          @author 作者 
           * 
          @version 創建時間:2009-11-5 下午05:19:19 
           * 類說明 
           
          */
          public class OnePerCustomerInterceptor implements MethodInterceptor {
              
          //定義包含用戶的集合
              private Set customers = new HashSet();
              
          /*
               * 當你在方法調用的前后都需要交叉切面邏輯時,應該使用MethodInterceptor。由于你必須要記得顯示調用
               * invocation.proceed()方法,所以,在滿足要求的情況下,最好還是使用MethodBeforeAdvice或
               * AfterReturningAdvice.
               
          */
              
              
          public Object invoke(MethodInvocation invocation) throws Throwable {
                   Customer customer 
          = (Customer)invocation.getArguments()[0];
                   
          if(customers.contains(customer)){
                       System.out.println(
          "拋出異常");
                   }
                   
          //調用目標方法
                   Object squishee = invocation.proceed();
                   
          //添加用戶
                   customers.add(customer);
                   
          //返回目標方法結果
                  return squishee;
              }
          }



             
          posted on 2009-11-05 17:31 王永慶 閱讀(229) 評論(0)  編輯  收藏 所屬分類: SPRING
          <2009年11月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          關注blogs

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 迁安市| 高邮市| 怀仁县| 会理县| 胶州市| 嫩江县| 定陶县| 彩票| 汉寿县| 临洮县| 五家渠市| 丰原市| 民勤县| 洛隆县| 册亨县| 河南省| 噶尔县| 滕州市| 石嘴山市| 浦北县| 保亭| 漯河市| 巨鹿县| 新丰县| 石嘴山市| 灵宝市| 宁远县| 鄂温| 湘西| 盐池县| 永平县| 静宁县| 竹北市| 兴仁县| 德江县| 秭归县| 栖霞市| 安国市| 开江县| 漯河市| 萝北县|