shenang博客技術文檔


          理論不懂就實踐,實踐不會就學理論!

          posts - 35,comments - 55,trackbacks - 0
           

                                   AOP學習筆記

                                       

          1 切面(Aspect

          切面,對象操作過程中的截面。這可能是AOP中最關鍵的一個術語。

          我們首先來看一個應用開發中常見的切面:用戶權限檢查。大概只要是完整的應用,都

          少不了用戶權限檢查這個模塊,不同身份的用戶可以做什么,不可以做什么,均由這個模塊

          加以判定。 而這個模塊調用的位置通常也比較固定:用戶發起請求之后, 執行業務邏輯之前。  

          針對權限檢查這一模塊進行分離,我們就得到了一個切面.

          切面意義何在?

          首先根據上例,假設我們實現了一個通用的權限檢查模塊,那么就可以在這層切面上進

          行統一的集中式權限管理。而業務邏輯組件則無需關心權限方面的問題。也就是說,通過切

          面,我們可以將系統中各個不同層次上的問題隔離開來,實現統一集約式處理。各切面只需

          集中于自己領域內的邏輯實現。

          這一方面使得開發邏輯更加清晰,專業化分工更加易于進行;另一方面,由于切面的隔

          離,降低了耦合性,我們就可以在不同的應用中將各個切面組合使用,從而使得代碼可重用

          性大大增強。

          2連接點(JoinPoint

          程序運行過程中的某個階段點。如某個方法調用,或者某個異常被拋出。

          3.處理邏輯(Advice

          在某個連接點所采用的處理邏輯

          處理邏輯的調用模式通常有三種:

          i. Around

          在連接點前后插入預處理過程和后處理過程。

          ii. Before

          僅在連接點之前插入預處理過程。

          iii. Throw

          在連接點拋出異常時進行異常處理。

          4.切點(PointCut

          一系列連接點的集合,它指明處理方式(Advice)將在何時被觸發。

                             Dynamic Proxy Spring AOP

          Dynamic ProxyJDK 1.3版本中新引入的一種動態代理機制。它是Proxy模式的一

          種動態實現版本。

          代碼:

          public class TxHandler implements InvocationHandler {

             private Object originalObject;

             public Object bind(Object obj) {

             this.originalObject = obj;

             return Proxy.newProxyInstance(

                obj.getClass().getClassLoader(),

                obj.getClass().getInterfaces(),

               this);

           }

           public Object invoke(Object proxy, Method method, Object[] args)

             throws Throwable {

               Object result = null;

             if (!method.getName().startsWith("save")) {

                UserTransaction tx = null;

               try {

                  tx = (UserTransaction) (

          new InitialContext().lookup("java/tx")

          );

                   result = method.invoke(originalObject, args);

                   tx.commit();

                 } catch (Exception ex) {

                 if (null != tx) {

                   try {

                      tx.rollback();

                    } catch (Exception e) {

                    }

                  }

                }

               } else {

                result = method.invoke(originalObject, args);

              }

              return result;

           }

          }

           在示例代碼中,我們為所有名稱以“save”開頭的方法追加了JTA事務管理。

          下面是夏昕老師在客戶培訓過程中編寫的一個Dynamic Proxy based AOP實現示例,非常簡單,有興趣的讀者可以看看。

          1AOPHandler .java

          public class AOPHandler implements InvocationHandler {

           private static Log logger = LogFactory.getLog(AOPHandler.class);

           private List interceptors = null;

           private Object originalObject;

           /**

           * 返回動態代理實例

           * @param obj

           * @return

           */

           public Object bind(Object obj) {

             this.originalObject = obj;

             return Proxy.newProxyInstance(obj.getClass().getClassLoader(),

          obj

                  .getClass().getInterfaces(), this);

           }

           /**

           * Invoke方法中,加載對應的Interceptor,并進行

           * 預處理(before)、后處理(after)以及異常處理(exceptionThrow)過程

           */

           public Object invoke(Object proxy, Method method, Object[] args)

               throws Throwable {

              Object result = null;

              Throwable ex = null;

              InvocationInfo invInfo = new InvocationInfo(proxy, method, args,

                  result, ex);

              logger.debug("Invoking Before Intercetpors!");

          invokeInterceptorsBefore(invInfo);

          try {

                logger.debug("Invoking Proxy Method!");

                result = method.invoke(originalObject, args);

                invInfo.setResult(result);

                logger.debug("Invoking After Method!");

                invokeInterceptorsAfter(invInfo);

              } catch (Throwable tr) {

                invInfo.setException(tr);

                logger.debug("Invoking exceptionThrow Method!");

                invokeInterceptorsExceptionThrow(invInfo);

               throw new AOPRuntimeException(tr);

              }

             return result;

           }

           /**

           * 加載Interceptor

           * @return

           */

           private synchronized List getIntercetors() {

             if (null == interceptors) {

                interceptors = new ArrayList();

               //Todo:讀取配置,加載Interceptor實例

               //interceptors.add(new MyInterceptor());

              }

             return interceptors;

           }

           /**

           * 執行預處理方法

           * @param invInfo

           */

           private void invokeInterceptorsBefore(InvocationInfo invInfo) {

              List interceptors = getIntercetors();

             int len = interceptors.size();

          for (int i = 0; i < len; i++) {

                ((Interceptor) interceptors.get(i)).before(invInfo);

              }

           }

           /**

           * 執行后處理方法

           * @param invInfo

           */

           private void invokeInterceptorsAfter(InvocationInfo invInfo) {

              List interceptors = getIntercetors();

             int len = interceptors.size();

             for (int i = len - 1; i >= 0; i--) {

                ((Interceptor) interceptors.get(i)).after(invInfo);

              }

           }

           /**

           * 執行異常處理方法

           * @param invInfo

           */

           private void invokeInterceptorsExceptionThrow(InvocationInfo

          invInfo) {

              List interceptors = getIntercetors();

             int len = interceptors.size();

             for (int i = len - 1; i >= 0; i--) {

                ((Interceptor)

          interceptors.get(i)).exceptionThrow(invInfo);

              }

           }

          }

          2Interceptor .java:

           

          public interface Interceptor {

           public void before(InvocationInfo invInfo);

           public void after(InvocationInfo invInfo);

           public void exceptionThrow(InvocationInfo invInfo); 

          }

          3InvocationInfo.java:

           

          public class InvocationInfo {

           Object proxy;

           Method method;

           Object[] args;

           Object result;

           Throwable Exception;

           public InvocationInfo(Object proxy, Method method, Object[] args,

                Object result, Throwable exception) {

             super();

             this.proxy = proxy;

             this.method = method;

             this.args = args;

             this.result = result;

              Exception = exception;

           }

           public Object getResult() {

             return result;

           }

           public void setResult(Object result) {

             this.result = result;

           }

           public Object[] getArgs() {

             return args;

           }

           public void setArgs(Object[] args) {

             this.args = args;

           }

           public Throwable getException() {

             return Exception;

           }

           public void setException(Throwable exception) {

              Exception = exception;

           }

           public Method getMethod() {

             return method;

           }

           public void setMethod(Method method) {

             this.method = method;

           }

           public Object getProxy() {

             return proxy;

           }

           public void setProxy(Object proxy) {

             this.proxy = proxy;

           }

          }

          4AOPFactory.java

           

          public class AOPFactory {

           private static Log logger = LogFactory.getLog(AOPFactory.class);

           /**

           * 根據類名創建類實例

           * @param clzName

           * @return

           * @throws ClassNotFoundException

           */

           public static Object getClassInstance(String clzName){

              Class cls;

             try {

                cls = Class.forName(clzName);

               return (Object)cls.newInstance();

              } catch (ClassNotFoundException e) {

                logger.debug(e);

               throw new AOPRuntimeException(e);

              } catch (InstantiationException e) {

                logger.debug(e);

               throw new AOPRuntimeException(e);     

              } catch (IllegalAccessException e) {

                logger.debug(e);

               throw new AOPRuntimeException(e);     

              }

           }

             /**

           * 根據傳入的類名,返回AOP代理對象

           * @param clzName

           * @return

           */

           public static Object getAOPProxyedObject(String clzName){

          AOPHandler txHandler = new AOPHandler();

              Object obj = getClassInstance(clzName);

             return txHandler.bind(obj);

           }

          }

          5MyInterceptor .java

          public class MyInterceptor implements Interceptor{

           private static Log logger = LogFactory.getLog(MyInterceptor.class);

           public void before(InvocationInfo invInfo) {

              logger.debug("Pre-processing");

           }

           public void after(InvocationInfo invInfo) {

              logger.debug("Post-processing");   

           }

           public void exceptionThrow(InvocationInfo invInfo) {

              logger.debug("Exception-processing");

           }

          }

          posted on 2009-03-25 11:09 重慶理工小子 閱讀(320) 評論(0)  編輯  收藏 所屬分類: Spring2
          主站蜘蛛池模板: 定日县| 苍溪县| 德昌县| 黄梅县| 六枝特区| 柘荣县| 都兰县| 崇礼县| 广灵县| 南皮县| 巨鹿县| 莎车县| 沾益县| 高青县| 忻州市| 和田县| 甘孜县| 平陆县| 嵩明县| 依安县| 靖边县| 牙克石市| 论坛| 罗山县| 定边县| 天气| 乡宁县| 枞阳县| 荥经县| 永善县| 天峻县| 安宁市| 金川县| 马山县| 合江县| 孟州市| 固阳县| 岳普湖县| 汝南县| 漠河县| 楚雄市|