shenang博客技術(shù)文檔


          理論不懂就實(shí)踐,實(shí)踐不會(huì)就學(xué)理論!

          posts - 35,comments - 55,trackbacks - 0
           

                                   AOP學(xué)習(xí)筆記

                                       

          1 切面(Aspect

          切面,對(duì)象操作過程中的截面。這可能是AOP中最關(guān)鍵的一個(gè)術(shù)語(yǔ)。

          我們首先來看一個(gè)應(yīng)用開發(fā)中常見的切面:用戶權(quán)限檢查。大概只要是完整的應(yīng)用,都

          少不了用戶權(quán)限檢查這個(gè)模塊,不同身份的用戶可以做什么,不可以做什么,均由這個(gè)模塊

          加以判定。 而這個(gè)模塊調(diào)用的位置通常也比較固定:用戶發(fā)起請(qǐng)求之后, 執(zhí)行業(yè)務(wù)邏輯之前。  

          針對(duì)權(quán)限檢查這一模塊進(jìn)行分離,我們就得到了一個(gè)切面.

          切面意義何在?

          首先根據(jù)上例,假設(shè)我們實(shí)現(xiàn)了一個(gè)通用的權(quán)限檢查模塊,那么就可以在這層切面上進(jìn)

          行統(tǒng)一的集中式權(quán)限管理。而業(yè)務(wù)邏輯組件則無需關(guān)心權(quán)限方面的問題。也就是說,通過切

          面,我們可以將系統(tǒng)中各個(gè)不同層次上的問題隔離開來,實(shí)現(xiàn)統(tǒng)一集約式處理。各切面只需

          集中于自己領(lǐng)域內(nèi)的邏輯實(shí)現(xiàn)。

          這一方面使得開發(fā)邏輯更加清晰,專業(yè)化分工更加易于進(jìn)行;另一方面,由于切面的隔

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

          性大大增強(qiáng)。

          2連接點(diǎn)(JoinPoint

          程序運(yùn)行過程中的某個(gè)階段點(diǎn)。如某個(gè)方法調(diào)用,或者某個(gè)異常被拋出。

          3.處理邏輯(Advice

          在某個(gè)連接點(diǎn)所采用的處理邏輯

          處理邏輯的調(diào)用模式通常有三種:

          i. Around

          在連接點(diǎn)前后插入預(yù)處理過程和后處理過程。

          ii. Before

          僅在連接點(diǎn)之前插入預(yù)處理過程。

          iii. Throw

          在連接點(diǎn)拋出異常時(shí)進(jìn)行異常處理。

          4.切點(diǎn)(PointCut

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

                             Dynamic Proxy Spring AOP

          Dynamic ProxyJDK 1.3版本中新引入的一種動(dòng)態(tài)代理機(jī)制。它是Proxy模式的一

          種動(dòng)態(tài)實(shí)現(xiàn)版本。

          代碼:

          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;

           }

          }

           在示例代碼中,我們?yōu)樗忻Q以“save”開頭的方法追加了JTA事務(wù)管理。

          下面是夏昕老師在客戶培訓(xùn)過程中編寫的一個(gè)Dynamic Proxy based AOP實(shí)現(xiàn)示例,非常簡(jiǎn)單,有興趣的讀者可以看看。

          1、AOPHandler .java

          public class AOPHandler implements InvocationHandler {

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

           private List interceptors = null;

           private Object originalObject;

           /**

           * 返回動(dòng)態(tài)代理實(shí)例

           * @param obj

           * @return

           */

           public Object bind(Object obj) {

             this.originalObject = obj;

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

          obj

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

           }

           /**

           * Invoke方法中,加載對(duì)應(yīng)的Interceptor,并進(jìn)行

           * 預(yù)處理(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實(shí)例

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

              }

             return interceptors;

           }

           /**

           * 執(zhí)行預(yù)處理方法

           * @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);

              }

           }

           /**

           * 執(zhí)行后處理方法

           * @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);

              }

           }

           /**

           * 執(zhí)行異常處理方法

           * @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);

              }

           }

          }

          2、Interceptor .java:

           

          public interface Interceptor {

           public void before(InvocationInfo invInfo);

           public void after(InvocationInfo invInfo);

           public void exceptionThrow(InvocationInfo invInfo); 

          }

          3、InvocationInfo.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;

           }

          }

          4、AOPFactory.java

           

          public class AOPFactory {

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

           /**

           * 根據(jù)類名創(chuàng)建類實(shí)例

           * @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);     

              }

           }

             /**

           * 根據(jù)傳入的類名,返回AOP代理對(duì)象

           * @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 重慶理工小子 閱讀(322) 評(píng)論(0)  編輯  收藏 所屬分類: Spring2
          主站蜘蛛池模板: 巴南区| 苏尼特左旗| 台南县| 女性| 固镇县| 昌平区| 潮安县| 东丽区| 新昌县| 泰宁县| 宝坻区| 承德县| 逊克县| 阜新市| 兰西县| 临潭县| 隆德县| 宁武县| 都安| 巫山县| 鄂托克前旗| 甘肃省| 大关县| 北辰区| 古丈县| 乌兰县| 亚东县| 保定市| 长汀县| 东兰县| 九龙城区| 常山县| 佳木斯市| 灌阳县| 襄樊市| 长泰县| 富平县| 商洛市| 青川县| 花垣县| 南平市|