paulwong

          Spring 2.x AOP 配置方式整理

          讓我們假定你所有的服務層類定義在以 'x.y.service' 為根的包內。 為了讓service包(或子包)下所有名字以 'Service' 結尾的類的對象擁有默認的事務語義,你可以做如下的配置:


          <aop:config>  
            
            
          <aop:pointcut id="serviceOperation"  
                  expression
          ="execution(* x.y.service..*Service.*(..))"/>  
            
            
          <aop:advisor pointcut-ref="serviceOperation" advice-ref="txAdvice"/>  
            
          </aop:config>  
            
          <!-- these two beans will be transactional -->  
          <bean id="fooService" class="x.y.service.DefaultFooService"/>  
          <bean id="barService" class="x.y.service.extras.SimpleBarService"/>  
            
          <!--  and these two beans won't -->  
          <bean id="anotherService" class="org.xyz.SomeService"/> <!-- (not in the right package) -->  
          <bean id="barManager" class="x.y.service.SimpleBarManager"/> <!-- (doesn't end in 'Service') -->  
            
          <tx:advice id="txAdvice">  
            
          <tx:attributes>  
              
          <tx:method name="get*" read-only="true"/>  
              
          <tx:method name="*"/>  
            
          </tx:attributes>  
          </tx:advice>  


          下面的配置示例演示了兩個擁有完全不同的事務配置的bean。



          <aop:config>  
            
            
          <aop:pointcut id="defaultServiceOperation"  
                  expression
          ="execution(* x.y.service.*Service.*(..))"/>  
            
            
          <aop:pointcut id="noTxServiceOperation"  
                  expression
          ="execution(* x.y.service.ddl.DefaultDdlManager.*(..))"/>  
            
            
          <aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>  
            
            
          <aop:advisor pointcut-ref="noTxServiceOperation" advice-ref="noTxAdvice"/>  
            
          </aop:config>  
            
          <!-- this bean will be transactional (see the 'defaultServiceOperation' pointcut) -->  
          <bean id="fooService" class="x.y.service.DefaultFooService"/>  
            
          <!-- this bean will also be transactional, but with totally different transactional settings -->  
          <bean id="anotherFooService" class="x.y.service.ddl.DefaultDdlManager"/>  
            
          <tx:advice id="defaultTxAdvice">  
            
          <tx:attributes>  
              
          <tx:method name="get*" read-only="true"/>  
              
          <tx:method name="*"/>  
            
          </tx:attributes>  
          </tx:advice>  
            
          <tx:advice id="noTxAdvice">  
            
          <tx:attributes>  
              
          <tx:method name="*" propagation="NEVER"/>  
            
          </tx:attributes>  
          </tx:advice>  



          在service接口所有的方法上執行的一個業務service方法。這里的定義假設所有的接口都被
          放置在service包內,它們的實現被放置在service包的子包內。
          如果你按照功能對接口進行分組(例如:包com.xyz.someapp.abc.service,com.xyz.def.service),
          則這種情況下這個切點表達式應該是:"execution(* com.xyz.someapp..service.*.*(..))"




          /**  
           * A business service is the execution of any method defined on a service  
           * interface. This definition assumes that interfaces are placed in the  
           * "service" package, and that implementation types are in sub-packages.  
           *   
           * If you group service interfaces by functional area (for example,   
           * in packages com.xyz.someapp.abc.service and com.xyz.def.service) then  
           * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))"  
           * could be used instead.  
           *  
           * Alternatively, you can write the expression using the 'bean'  
           * PCD, like so "bean(*Service)". (This assumes that you have  
           * named your Spring service beans in a consistent fashion.)  
          */
            
          @Pointcut(
          "execution(* com.xyz.someapp.service.*.*(..))")   
          public void businessService() {}  



          在dao接口上定義的所有方法內執行一個數據訪問操作。這個定義假設所有的dao接口定義
          在dao包內,實現被放置在了子包內。




          /**  
           * A data access operation is the execution of any method defined on a   
           * dao interface. This definition assumes that interfaces are placed in the  
           * "dao" package, and that implementation types are in sub-packages.  
          */
            
          @Pointcut(
          "execution(* com.xyz.someapp.dao.*.*(..))")   
          public void dataAccessOperation() {}  



          任何一個名字以“set”開始的方法的執行:




          execution(* set*(..))  



          AccountService 接口定義的任意方法的執行:




          execution(* com.xyz.service.AccountService.*(..))  



          在service包中定義的任意方法的執行:




          execution(* com.xyz.service.*.*(..))  



          在service包或其子包中定義的任意方法的執行:




          execution(* com.xyz.service..*.*(..)) 



          其他的例子:
          --------------------------------------------------------------------------------


          兩個數據源,兩個數據庫事務攔截器,兩個數據庫事物切點。
          execution組合表達式表述數據庫事務切點:
          大部分service類的方法使用數據源txManager-datasourceone,對應事物切點txPointcut-datasourceone,事物攔截器txAdvice-datasourceone;
          service層PublishService類的幾個方法使用數據源txManager-datasourcetwo,對應事物切點txPointcut-datasourcetwo,事物攔截器txAdvice-datasourcetwo;
          一個自定義方法攔截器RuntimeLogInterceptor(攔截每個方法,并記錄每個方法的執行日志),攔截切點runtimeLogInterceptorPoint;




          <!-- 數據源1事務管理器 -->  
          <bean id="txManager-datasourceone" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
            
          <property name="dataSource" ref="DataSource"/>  
          </bean>  
            
          <!-- 數據源2事務管理器 -->  
          <bean id="txManager-datasourcetwo" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
            
          <property name="dataSource" ref="srcDataSource"/>  
          </bean>  
                 
          <!-- 數據源1事務攔截器 -->  
          <tx:advice id="txAdvice-datasourceone" transaction-manager="txManager-datasourceone" >  
            
          <tx:attributes>  
              
          <tx:method name="get*" read-only="true"/>  
              
          <tx:method name="*"/>  
            
          </tx:attributes>  
          </tx:advice>  
            
          <!-- 數據源2事務攔截器 -->  
          <tx:advice id="txAdvice-datasourcetwo" transaction-manager="txManager-datasourcetwo" >  
            
          <tx:attributes>  
              
          <tx:method name="get*" read-only="true"/>  
              
          <tx:method name="*"/>  
            
          </tx:attributes>  
          </tx:advice>  
            
          <!-- aop配置 強制使用cglib代理 -->  
          <aop:config proxy-target-class="true">  
            
            
          <!-- datasourceone 數據庫事務管理切點    
                 包含的方法:service包(或子包)下所有名字以 'Service' 結尾的類內所有的方法。   
                 不包含的方法:x.y.service包下PublishService類的getResCategory(..)方法,   
                 getEditorResList(..)方法,updateResbackrmd(..)方法   
            
          -->  
            
          <aop:pointcut id="txPointcut-datasourceone"    
              expression
          ="execution(* x.y.service..*Service.*(..))    
                and !execution(* x.y.service.PublishService.getResCategory(..))    
                and !execution(* x.y.service.PublishService.getEditorResList(..))    
                and !execution(* x.y.service.PublishService.updateResbackrmd(..))"
          />  
            
            
          <!-- datasourcetwo 數據庫事務管理切點    
                 包含的方法:x.y.service包PublishService類的getResCategory(..)方法,   
                 getEditorResList(..)方法,updateResbackrmd(..)方法。   
            
          -->                                                   
            
          <aop:pointcut id="txPointcut-datasourcetwo"    
              expression
          ="execution(* x.y.service.PublishService.getResCategory(..))    
                or execution(* x.y.service.PublishService.getEditorResList(..))    
                or execution(* x.y.service.PublishService.updateResbackrmd(..))"
          />  
            
            
          <!-- 運行日志攔截點    
                 包含的方法:service包(或子包)下所有名字以 'Service' 結尾的類內所有的方法。   
                 不包含的方法:x.y.service包RuntimeLogService類createRuntimeLogBeforeRequest(..)方法,   
              getRuntimeLog(..)方法,setRuntimeLog(..)方法,completeRuntimeLogAfterRequest(..)方法。   
            
          -->  
            
          <aop:pointcut id="runtimeLogInterceptorPoint"    
              expression
          ="execution(* x.y.service..*Service.*(..))    
                and !execution(* x.y.service.RuntimeLogService.createRuntimeLogBeforeRequest(..))    
                and !execution(* x.y.service.RuntimeLogService.getRuntimeLog(..))    
                and !execution(* x.y.service.RuntimeLogService.setRuntimeLog(..))    
                and !execution(* x.y.service.RuntimeLogService.completeRuntimeLogAfterRequest(..))"
          />  
                         
            
          <!-- 運行日志攔截 -->  
            
          <aop:advisor advice-ref="RuntimeLogInterceptor" pointcut-ref="runtimeLogInterceptorPoint"/>  
            
          <!-- datasourceone,datasourcetwo數據庫事務攔截 -->  
            
          <aop:advisor advice-ref="txAdvice-datasourceone" pointcut-ref="txPointcut-datasourceone"/>  
            
          <aop:advisor advice-ref="txAdvice-datasourcetwo" pointcut-ref="txPointcut-datasourcetwo"/>  
            
          </aop:config>  



          總結一下:
          --------------------------------------------------------------------------------

           

          1,pointcut既可以定義在一個接口上面(表示實現該接口的類方法將被攔截),同時也可以定義在一個類上面(無接口的情
             況,需要強制使用cglib)。在接口上面定義pointcut時無需關心接口實現類的具體位置,只需要定義被攔截的接口及方
             法位置。

          2,常見的情況:
          x.y.service..*Service.*(..)
          x.y.service —— 包“x.y.service”
          x.y.service.. —— 包“x.y.service”及其子包例如:“x.y.service.abc”,“x.y.service.def”,“x.y.service.ghi”,“x.y.service.jkl”。。。
          *Service —— 定義接口(或沒有實現接口的類,需要使用cglib代理)表達式;所有以Service結尾的類或接口,注意不是所有以Service結尾的包名。
          *(..) —— 定義方法名,方法參數表達式;任意方法的名稱,任意方法參數。

          com.xyz.service.*.*(..)
          com.xyz.service —— 包“com.xyz.service”
          *.*(..) —— 任意接口(或沒有實現接口的類,需要使用cglib代理),任意方法,任意參數
          在service包下定義的任意方法的執行。

          com.xyz.service..*.*(..)
          com.xyz.service —— 包“com.xyz.service”
          com.xyz.service.. ——包“com.xyz.service”及其子包
          *.*(..) —— 任意接口(或沒有實現接口的類,需要使用cglib代理),任意方法,任意參數



          posted on 2009-03-11 10:16 paulwong 閱讀(906) 評論(0)  編輯  收藏 所屬分類: J2EE

          主站蜘蛛池模板: 大厂| 蕲春县| 兴义市| 龙山县| 许昌市| 铜山县| 左云县| 加查县| 深水埗区| 同心县| 昌图县| 静宁县| 保德县| 肃宁县| 突泉县| 涞水县| 屏边| 门源| 巴中市| 通许县| 胶南市| 启东市| 元江| 冕宁县| 汉寿县| 青海省| 孝感市| 逊克县| 腾冲县| 德州市| 巴马| 夏邑县| 丰镇市| 屯昌县| 镶黄旗| 阿拉善右旗| 敦化市| 淮阳县| 渭南市| 大同县| 赣州市|