hot的學(xué)習(xí)筆記

          我是一只弱小的毛毛蟲,想像有一天可以成為強(qiáng)壯的挖土機(jī), 擁有挖掘夢想的神奇手套。。。

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            8 隨筆 :: 0 文章 :: 1 評論 :: 0 Trackbacks
              前些日子西安項(xiàng)目中的任務(wù)日志,以及最近參與工作流動態(tài)表單開發(fā)中都使用到了spring的aop。所以,自己簡單的進(jìn)行了一下總結(jié),也算是對前一段時間工作的一個總結(jié)吧。

           AOPAspect-Oriented Programming,面向切面編程),可以說是OOP面向?qū)ο缶幊蹋┑难a(bǔ)充和完善。OOP引入封裝、繼承和多態(tài)性等概念來建立一種對象層次結(jié)構(gòu),用以模擬公共行為的一個集合。當(dāng)我們需要為分散的對象引入公共行為的時候,OOP則顯得無能為力。也就是說,OOP允許你定義從上到下的關(guān)系,但并不適合定義從左到右的關(guān)系。例如日志功能。日志代碼往往水平地散布在所有對象層次中,而與它所散布到的對象的核心功能毫無關(guān)系。對于其他類型的代碼,如安全性、異常處理和透明的持續(xù)性也是如此。這種散布在各處的無關(guān)的代碼被稱為橫切(cross-cutting)代碼,在OOP設(shè)計(jì)中,它導(dǎo)致了大量代碼的重復(fù),而不利于各個模塊的重用。

           而AOP技術(shù)則恰恰相反,它利用一種稱為“橫切”的技術(shù),剖解開封裝的對象內(nèi)部,并將那些影響了多個類的公共行為封裝到一個可重用模塊,并將其名為“Aspect”,即方面。所謂“方面”,簡單地說,就是將那些與業(yè)務(wù)無關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來,便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來的可操作性和可維護(hù)性。AOP代表的是一個橫向的關(guān)系,如果說“對象”是一個空心的圓柱體,其中封裝的是對象的屬性和行為;那么面向方面編程的方法,就仿佛一把利刃,將這些空心圓柱體剖開,以獲得其內(nèi)部的消息。而剖開的切面,也就是所謂的“方面”了。然后它又以巧奪天功的妙手將這些剖開的切面復(fù)原,不留痕跡。

              Spring支持四種攔截類型:目標(biāo)方法調(diào)用前(before),目標(biāo)方法調(diào)用后(after),目標(biāo)方法調(diào)用前后(around),以及目標(biāo)方法拋出異常(throw)。

              前置攔截的類必須實(shí)現(xiàn)MethodBeforeAdvice接口,實(shí)現(xiàn)其中的before方法。

              后置攔截的類必須實(shí)現(xiàn)AfterReturningAdvice接口,實(shí)現(xiàn)其中的afterReturning方法。

              環(huán)繞攔截的類必須實(shí)現(xiàn)MethodInterceptor接口,實(shí)現(xiàn)其中的invoke方法。環(huán)繞攔截是唯一可以控制目標(biāo)方法是否被真正調(diào)用的攔截類型,也可以控制返回對象。而前置攔截或后置攔截不能控制,它們不能印象目標(biāo)方法的調(diào)用和返回。
          但是以上的攔截的問題在于,不能對于特定方法進(jìn)行攔截,而只能對某個類的全部方法作攔截。所以下面引入了兩個新概念:切入點(diǎn)引入通知。

          切入點(diǎn)的定義相當(dāng)于更加細(xì)化地規(guī)定了哪些方法被哪些攔截器所攔截,而并非所有的方法都被所有的攔截器所攔截。在ProxyFactoryBean的屬性中,interceptorNames屬性的對象也由攔截(Advice)變成了引入通知(Advisor),正是在Advisor中詳細(xì)定義了切入點(diǎn)(PointCut)和攔截(Advice)的對應(yīng)關(guān)系,比如常見的基于名字的切入點(diǎn)匹配(NameMatchMethodPointcutAdvisor類)和基于正則表達(dá)式的切入點(diǎn)匹配(RegExpPointcutAdvisor類)。這些切入點(diǎn)都屬于靜態(tài)切入點(diǎn),因?yàn)樗麄冎辉诖韯?chuàng)建的時候被創(chuàng)建一次,而不是每次運(yùn)行都創(chuàng)建。

          下面是spring的配置文件 當(dāng)然aop的配置方式有許多種,這只是其中一種

           

          <!-- 獲取相應(yīng)的instance對象 并且不被aop攔截 -->
             
          <bean id="oaTaskInstanceService4Log" parent="transactionProxy">
                  
          <property name="target">
                      
          <bean
                          
          class="com.oa.task.service.impl.OaTaskInstanceServiceImpl">
                          
          <property name="oaTaskInstanceDao">
                              
          <ref local="oaTaskInstanceDao"/>
                          
          </property>
                      
          </bean>
                  
          </property>
              
          </bean>
             
          <!-- instance日志所需DAO -->
             
          <bean id="oaTaskInstanceLogDao" class="com.oa.task.dao.OaTaskInstanceLogDao">
                
          <property name="sessionFactory" ref="sessionFactory"></property>
             
          </bean>
             
          <!-- instance日志所需Service  此接口為 日志的業(yè)務(wù)操作接口-->
              
          <bean id="oaTaskInstanceLogService" parent="transactionProxy"> 
                  
          <property name="target">
                      
          <bean
                          
          class="com.oa.task.service.impl.OaTaskInstanceLogServiceImpl">
                          
          <property name="oaTaskInstanceLogDao">
                              
          <ref local="oaTaskInstanceLogDao"/>
                          
          </property>
                          
          <property name="sysOperDao">
                              
          <ref bean="sysOperDao" />
                          
          </property>
                          
          <property name="ibatisBase">
                              
          <ref bean="ibatisBase" />
                          
          </property>
                      
          </bean>
                  
          </property>
              
          </bean>
             
          <!-- instance日志AOP攔截類 -->
             
          <bean id="oaTaskInstanceLogOper" class="com.oa.task.log.OaTaskInstanceLogOper">
                     
          <property name="oaTaskInstanceLogService">
                      
          <ref local="oaTaskInstanceLogService" />
                  
          </property>
                  
          <property name="oaTaskInstanceService">
                      
          <ref local="oaTaskInstanceService4Log" />
                  
          </property>
             
          </bean>
             
             
          <!-- instance日志AOP配置綁定 -->
             
          <bean id="oaTaskInstanceLogAutoProxy" 
                    
          class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
                    
          <property name="beanNames">
                       
          <list>
                         
          <value>oaTaskInstanceService</value>  //攔截的業(yè)務(wù)接口 oaTaskInstanceService內(nèi)所有方法都進(jìn)行攔截
                       </list>
                    
          </property>
                    
          <property name="interceptorNames">
                       
          <list>
                          
          <value>oaTaskInstanceLogOper</value>  //攔截器
                       
          </list>
                    
          </property>
              
          </bean>
             下面是 攔截器oaTaskInstanceLogOper類,采用的是環(huán)繞攔截的方式。
          public class OaTaskInstanceLogOper  implements MethodInterceptor{
              /**
               * 當(dāng)更新動作發(fā)生時的記錄
               
          */
              
          public Object invoke(MethodInvocation invocation) throws Throwable {
                  String method 
          = invocation.getMethod().getName();
                  Object result 
          = null;
                  
          if(MODIFY_INSTANCE.equals(method)){//修改日志(業(yè)務(wù)邏輯 判斷方法)
                      ......//業(yè)務(wù)操作,進(jìn)行日志的記錄
                      result
          =invocation.proceed(); 
                  }
          else {//不做任何日志
                      result=invocation.proceed();//調(diào)用原來的方法
                  }
                  
          return result;
              }


          }


          posted on 2009-07-22 22:39 hot 閱讀(830) 評論(0)  編輯  收藏 所屬分類: j2ee

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 马山县| 宿迁市| 皋兰县| 长宁县| 商水县| 城口县| 大安市| 施秉县| 冕宁县| 宾阳县| 醴陵市| 库车县| 岳池县| 新竹市| 澎湖县| 江源县| 郑州市| 绥宁县| 崇义县| 阳朔县| 扬州市| 图们市| 张家港市| 定兴县| 麻阳| 九寨沟县| 富蕴县| 岳阳市| 甘肃省| 平原县| 康保县| 枣庄市| 慈利县| 昌宁县| 扎兰屯市| 若尔盖县| 凉山| 鹿泉市| 东源县| 冕宁县| 蒲城县|