posts - 66,  comments - 11,  trackbacks - 0
              Spring的AOP框架允許你將分散在系統(tǒng)中的功能塊放到一個(gè)地方-切面。重用通用功能的常用面向?qū)ο蠹夹g(shù)是使用繼承和委

          托模式。但由于基礎(chǔ)類在系統(tǒng)中到處使用,使用繼承會(huì)引起脆弱的繼承關(guān)系。委托模式比較笨拙,依然需要重復(fù)調(diào)用委托對(duì)象

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

          方修改代碼。交叉業(yè)務(wù)現(xiàn)在可以被模塊化到特定對(duì)象切面中。這樣做有2個(gè)好處,第一,現(xiàn)在每個(gè)業(yè)務(wù)邏輯放在一個(gè)地方,而不

          是分散到代碼的各個(gè)角落。第二,我們的服務(wù)模塊現(xiàn)在更加清晰,因?yàn)樗麄冎话麄兊暮诵墓δ埽o助功能轉(zhuǎn)移到切面中。

              切面(Aspect):切面是你要實(shí)現(xiàn)的交叉功能。切面最常用的例子是日志記錄。日志記錄在系統(tǒng)中到處需要用到。
              連接點(diǎn)(Joinpoint):連接點(diǎn)是應(yīng)用程序執(zhí)行過程中插入切面的地點(diǎn)。這個(gè)地點(diǎn)可以是方法調(diào)用,異常拋出,或者是要修改

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

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

              Spring的AOP實(shí)現(xiàn):
              在Spring中所有的通知都以Java類的形式編寫。代理Bean只有在第一次被應(yīng)用系統(tǒng)需要的時(shí)候才被創(chuàng)建。如果你使用的是ApplicationContext,代理對(duì)象在BeanFactory載入所有Bean的時(shí)候被創(chuàng)建。因?yàn)镾pring在運(yùn)行期創(chuàng)建代理,所以使用Spring AOP不需要特殊編譯期。
              Spring有2種代理創(chuàng)建方式。如果目標(biāo)對(duì)象實(shí)現(xiàn)了一個(gè)接口暴露的方法,Spring將使用JDK的Java.lang.reflect.Proxy類創(chuàng)建代理。這個(gè)類讓Spring動(dòng)態(tài)產(chǎn)生一個(gè)新的類,它實(shí)現(xiàn)了所需的接口,織入了通知,并且代理對(duì)目標(biāo)對(duì)象的所有請(qǐng)求。
              如果目標(biāo)對(duì)象沒有實(shí)現(xiàn)任何接口,Spring使用CGLIB庫生成目標(biāo)對(duì)象的子類。在創(chuàng)建這個(gè)子類的時(shí)候,Spring將通知織入,并且對(duì)目標(biāo)對(duì)象的調(diào)用委托給這個(gè)子類。

              通知包含了切面的邏輯。所以當(dāng)你創(chuàng)建一個(gè)通知對(duì)象的時(shí)候,你是在編寫實(shí)現(xiàn)交叉功能的代碼。而且,記住Spring的連接點(diǎn)模型是建立在方法攔截上。這意味著你編寫的Spring通知會(huì)在方法調(diào)用周圍的各個(gè)地方織入系統(tǒng)中。通知的類型有:Around,Before,After,Throws

          前置通知:需要擴(kuò)展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>
              
          <!-- 創(chuàng)建代理目標(biāo)對(duì)象 -->
              
          <bean id="kwikEMartTarget" class="com.springinaction.chapter03.store.ApuKwikEMart"></bean>
              
          <!-- 創(chuàng)建通知 -->
              
          <bean id="welcomeAdvice" class="com.springinaction.chapter03.store.WelcomeAdvice"></bean>
              
          <!-- 創(chuàng)建代理對(duì)象 -->
              
          <bean id="kwikEMart" class="org.springframework.aop.framework.ProxyFactoryBean">
                  
          <!-- 代理類實(shí)現(xiàn)的接口 -->
                  
          <property name="proxyInterfaces">
                      
          <value>com.springinaction.chaper03.store.kwikEMart</value>
                  
          </property>
                  
          <!-- 要織入的通知 -->
                  
          <property name="interceptorNames">
                      
          <list>
                          
          <value>welcomeAdvice</value>
                      
          </list>
                  
          </property>
                  
          <!-- 要代理的目標(biāo)對(duì)象 -->
                  
          <property name="target">
                      
          <ref bean="kwikEMartTarget"/>
                  
          </property>
              
          </bean>
          </beans>

          ProxyFactoryBean類是一個(gè)在BeanFactory中顯示的創(chuàng)建代理對(duì)象的中心類。像我們展示的那樣,你可以給它一個(gè)要實(shí)現(xiàn)的接口,一個(gè)要代理的目標(biāo)對(duì)象,一個(gè)要織入的通知,并且它將創(chuàng)建一個(gè)嶄新的代理對(duì)象。通常配置ProxyFactoryBean,讓它實(shí)現(xiàn)和目標(biāo)對(duì)象一樣的接口。

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

          環(huán)繞通知:需要實(shí)現(xiàn)MethodInterceptor,同時(shí)實(shí)現(xiàn)前置和后置通知
          public interface MethodInterceptor extends Interceptor{
              Object invoke(MethodInvocation invocation)throws Throwable;
          }
          MethodInterceptor接口和前面介紹的2種通知不同點(diǎn):
          1、MethodInterceptor能夠控制目標(biāo)方法是否真的被調(diào)用。通過調(diào)用MethodInvocation.proceed()方法來調(diào)用目標(biāo)方法。這一點(diǎn)不同于前兩個(gè),目標(biāo)方法總是被調(diào)用的。
          2、MethodInterceptor讓你可以控制返回的對(duì)象。就是說你可以返回一個(gè)與proceed()方法返回對(duì)象完全不同的對(duì)象。
          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 創(chuàng)建時(shí)間:2009-11-5 下午05:19:19 
           * 類說明 
           
          */
          public class OnePerCustomerInterceptor implements MethodInterceptor {
              
          //定義包含用戶的集合
              private Set customers = new HashSet();
              
          /*
               * 當(dāng)你在方法調(diào)用的前后都需要交叉切面邏輯時(shí),應(yīng)該使用MethodInterceptor。由于你必須要記得顯示調(diào)用
               * invocation.proceed()方法,所以,在滿足要求的情況下,最好還是使用MethodBeforeAdvice或
               * AfterReturningAdvice.
               
          */
              
              
          public Object invoke(MethodInvocation invocation) throws Throwable {
                   Customer customer 
          = (Customer)invocation.getArguments()[0];
                   
          if(customers.contains(customer)){
                       System.out.println(
          "拋出異常");
                   }
                   
          //調(diào)用目標(biāo)方法
                   Object squishee = invocation.proceed();
                   
          //添加用戶
                   customers.add(customer);
                   
          //返回目標(biāo)方法結(jié)果
                  return squishee;
              }
          }



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

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          關(guān)注blogs

          搜索

          •  

          最新評(píng)論

          • 1.?re: 心中的那個(gè)她[未登錄]
          • 如果心情能那么容易放開就好了,碰到她是我的緣分,但是她的緣分不知道在哪里。
          • --王永慶
          • 2.?re: 心中的那個(gè)她[未登錄]
          • 兄弟,喜歡就大膽去追好了,就是因?yàn)橄矚g才會(huì)有不愉快,如果想一輩子沒有這些煩惱,找一個(gè)可有可無的人就好了。這種事講的是緣分吧。別人對(duì)你好不好其實(shí)不太重要。放開心情就好了。
          • --萍水相逢
          • 3.?re: 心中的那個(gè)她
          • 只能同甘不能共苦,就他媽算了吧,程序員也是人啊!我現(xiàn)在也很討厭女的不理解人情。
          • --咖啡妝
          • 4.?re: 難以割舍的那份情感
          • 評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
          • --王永慶
          • 5.?re: 難以割舍的那份情感
          • 評(píng)論內(nèi)容較長(zhǎng),點(diǎn)擊標(biāo)題查看
          • --隔葉黃鶯

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 阜平县| 吉隆县| 景泰县| 芜湖县| 城市| 涟源市| 老河口市| 浮梁县| 龙山县| 哈尔滨市| 峨山| 健康| 普宁市| 万盛区| 淳安县| 昌图县| 通江县| 曲松县| 清水河县| 景泰县| 长葛市| 腾冲县| 衡南县| 广元市| 灌云县| 广德县| 鹿泉市| 长岭县| 泰兴市| 西乌珠穆沁旗| 垫江县| 彰化县| 齐齐哈尔市| 九江县| 宜昌市| 揭东县| 满洲里市| 邯郸县| 沐川县| 金湖县| 安宁市|