paulwong

          Spring 2.x AOP 配置方式整理

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


          <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>  


          下面的配置示例演示了兩個擁有完全不同的事務(wù)配置的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接口所有的方法上執(zhí)行的一個業(yè)務(wù)service方法。這里的定義假設(shè)所有的接口都被
          放置在service包內(nèi),它們的實現(xiàn)被放置在service包的子包內(nèi)。
          如果你按照功能對接口進(jìn)行分組(例如:包com.xyz.someapp.abc.service,com.xyz.def.service),
          則這種情況下這個切點表達(dá)式應(yīng)該是:"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接口上定義的所有方法內(nèi)執(zhí)行一個數(shù)據(jù)訪問操作。這個定義假設(shè)所有的dao接口定義
          在dao包內(nèi),實現(xiàn)被放置在了子包內(nèi)。




          /**  
           * 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”開始的方法的執(zhí)行:




          execution(* set*(..))  



          AccountService 接口定義的任意方法的執(zhí)行:




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



          在service包中定義的任意方法的執(zhí)行:




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



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




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



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


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




          <!-- 數(shù)據(jù)源1事務(wù)管理器 -->  
          <bean id="txManager-datasourceone" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
            
          <property name="dataSource" ref="DataSource"/>  
          </bean>  
            
          <!-- 數(shù)據(jù)源2事務(wù)管理器 -->  
          <bean id="txManager-datasourcetwo" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
            
          <property name="dataSource" ref="srcDataSource"/>  
          </bean>  
                 
          <!-- 數(shù)據(jù)源1事務(wù)攔截器 -->  
          <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>  
            
          <!-- 數(shù)據(jù)源2事務(wù)攔截器 -->  
          <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配置 強(qiáng)制使用cglib代理 -->  
          <aop:config proxy-target-class="true">  
            
            
          <!-- datasourceone 數(shù)據(jù)庫事務(wù)管理切點    
                 包含的方法:service包(或子包)下所有名字以 'Service' 結(jié)尾的類內(nèi)所有的方法。   
                 不包含的方法: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 數(shù)據(jù)庫事務(wù)管理切點    
                 包含的方法: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' 結(jié)尾的類內(nèi)所有的方法。   
                 不包含的方法: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數(shù)據(jù)庫事務(wù)攔截 -->  
            
          <aop:advisor advice-ref="txAdvice-datasourceone" pointcut-ref="txPointcut-datasourceone"/>  
            
          <aop:advisor advice-ref="txAdvice-datasourcetwo" pointcut-ref="txPointcut-datasourcetwo"/>  
            
          </aop:config>  



          總結(jié)一下:
          --------------------------------------------------------------------------------

           

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

          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 —— 定義接口(或沒有實現(xiàn)接口的類,需要使用cglib代理)表達(dá)式;所有以Service結(jié)尾的類或接口,注意不是所有以Service結(jié)尾的包名。
          *(..) —— 定義方法名,方法參數(shù)表達(dá)式;任意方法的名稱,任意方法參數(shù)。

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

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



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

          主站蜘蛛池模板: 鱼台县| 双城市| 镇巴县| 波密县| 江北区| 大港区| 临沭县| 上栗县| 芮城县| 彭泽县| 大厂| 石狮市| 永登县| 花垣县| 攀枝花市| 吴旗县| 濉溪县| 阜阳市| 大冶市| 盐津县| 黄大仙区| 崇阳县| 四川省| 柳江县| 綦江县| 盐津县| 宿州市| 宽城| 洪雅县| 尼玛县| 临沭县| 军事| 宣威市| 柳河县| 萨嘎县| 贵溪市| 平安县| 梅州市| 芮城县| 东港市| 正镶白旗|