1. 程式人生 > > Spring面向切面程式設計的三種方式以及常用相關案例總結

Spring面向切面程式設計的三種方式以及常用相關案例總結

Spring面向切面程式設計

==================================================

spring面向切面程式設計的方法之一:實現介面方式

1.執行前增強:MethodBeforeAdvice介面

標示方法:public void before(Method arg0, Object[] arg1, Object arg2){}

Method arg0----目標方法, Object[] arg1----方法中的引數, Object arg2----目標物件

2.執行後增強:AfterReturningAdvice介面

標示方法:public void afterReturning(Object arg0, Method arg1, Object[] arg2,Object arg3) throws Throwable {}

Object arg0-----返回值, Method arg1----目標方法, Object[] arg2----方法中的引數,Object arg3----目標物件

3.異常丟擲時增強:ThrowAdvice介面

標示方法:public void afterThrowing(Method method, Object[] args, Object target,SQLException ex) {}

Method method----目標方法, Object[] args----方法中的引數, Object target----目標物件,SQLException ex------特定的異常物件,即該異常時才會使用增強方法

4.環繞增強:MethodInterceptor

標示方法:public Object invoke(MethodInvocation arg0) throws Throwable {}

Object target = arg0.getThis(); // 獲取被代理物件

Method method = arg0.getMethod(); // 獲取被代理方法

Object[] args = arg0.getArguments(); // 獲取方法引數

Object result = arg0.proceed(); // 呼叫目標方法,獲取目標方法返回值--------注意丟擲異常,用來定義異常是的輸出。

5.使用的是aop標籤:定義bean用來指代特定的需呼叫的切面的類,後織入增強(定義切點以及增強)

<bean id="beforeAdvice" class="com.yunhe.aspect.BeforeAdvice"></bean>

<aop:config>

<aop:pointcut expression="execution(* com.yunhe.biz.*.*(..))" id="pc1"/>

<aop:advisor advice-ref="beforeAdvice" pointcut-ref="pc1"/>

</aop:config>

==================================================

spring面向切面程式設計的方法之二:註解方式

1.使用@Aspect標示類,表明該類是使用註解是實現增強

2.執行前增強:@Before("execution(* biz.IUserBiz.*(..))")   

標示方法:public void before() {}

3.執行後增強:@AfterReturning("execution(* biz.IUserBiz.*(..))")  

標示方法:public void afterReturning() {}

4.異常丟擲時增強:@AfterThrowing(pointcut = "execution(* biz.IUserBiz.*(..))", throwing = "e")

標示方法:public void afterThrowing(JoinPoint jp, RuntimeException e) {}

5.環繞增強:@Around("execution(* biz.IUserBiz.*(..))")

標示方法:public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {}

6.最終增強:@After("execution(* biz.IUserBiz.*(..))")

標示方法:public void afterLogger(JoinPoint jp) {}

7.spring容器標示類的存在,使用aop標籤在容器中表明使用註解方式進行增強

<bean class="aop.UserBizLogger"></bean>

<aop:aspectj-autoproxy />

8.JoinPoint jp的方法:

Object target = jp.getTarget(); // 獲取被代理物件

Method method = jp.getSignature(); // 獲取被代理方法

Object[] args = jp.getArgs(); // 獲取方法引數,通常Arrays.toString(jp.getArgs())轉化後用來輸出引數表列

Object result = jp.proceed(); // 呼叫目標方法,獲取目標方法返回值--------注意丟擲異常,用來定義異常是的輸出。

==================================================

spring面向切面程式設計的方法之三:Schema方式:普通JavaBean使用aop標籤在容器中定義

1.前置增強:<aop:after>

標示方法:public void before(JoinPoint  jp) {}

2.後置增強:<aop:after-returning>

標示方法:public void afterReturning(JoinPoint  jp, Object  result) {}

3.異常丟擲時增強:<aop:after-throwing>

標示方法:public void afterThrowing(JoinPoint  jp,  RuntimeException  e) {}

4.環繞增強:<aop:around>

標示方法: public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {}

5.最終增強:<aop:aspect>

標示方法:public void afterLogger(JoinPoint  jp) {}

6.定義增強類,織入(定義切點,織入)

<bean id="theLogger" class="aop. AfterLogger"></bean>

<aop:config>

    <aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" />

    <aop:aspect ref="theLogger">

        <aop:after  method="afterLogger"  pointcut-ref="pointcut" />

    </aop:aspect>

</aop:config>


Aop切面程式設計的幾個例子

==================================================

例一:log4j實現記錄日誌---介面

1.實現方式:利用實現介面的Aop方法給特定方法執行後置增強

2.步驟:新增log4j.propertiessrc下,以及log4j-1.2.17.jar新增lib

3.實現類實現介面用來定義

public class AfterAdvice implements AfterReturningAdvice {  

    Logger logger = Logger.getLogger(AfterAdvice.class);  

    public void afterReturning(Object arg0, Method arg1, Object[] arg2,  

            Object arg3) throws Throwable {  

        // TODO Auto-generated method stub  

        logger.debug("後置:執行物件:" + arg3 + "的方法為:" + arg1.getName() );  

    }  

}

4.Spring容器中定義切入方式(一個點多個面,一個面多個點均可)

  <bean id="beforeAdvice" class="com.yunhe.aspect.BeforeAdvice"></bean>  

    <bean id="afterAdvice" class="com.yunhe.aspect.AfterAdvice"></bean>  

    <aop:config>  

        <aop:pointcut expression="execution(* com.yunhe.biz.*.*(..))" id="pc1"/>  

        <aop:advisor advice-ref="beforeAdvice" pointcut-ref="pc1"/>  

        <aop:advisor advice-ref="afterAdvice" pointcut-ref="pc1"/>  

    </aop:config>  

5.log4j.properties的配置檔案資訊

1. ### ÉèÖÃLoggerÊä³ö¼¶±ðºÍÊä³öÄ¿µÄµØ ###  

2. log4j.rootLogger=debug, stdout,logfile  

3.   

4. ### °ÑÈÕÖ¾ÐÅÏ¢Êä³öµ½¿ØÖÆÌ¨ ###  

5. log4j.appender.stdout=org.apache.log4j.ConsoleAppender  

6. log4j.appender.stdout.Target=System.err  

7. log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout  

8.   

9. ### °ÑÈÕÖ¾ÐÅÏ¢Êä³öµ½Îļþ£ºjbit.log ###  

10. log4j.appender.logfile=org.apache.log4j.FileAppender  

11. log4j.appender.logfile.File=jbit.log  

12. log4j.appender.logfile.layout=org.apache.log4j.PatternLayout  

13. log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %F %p %m%n  

6.

==================================================

例二:環繞增強---介面

1.實現方式:利用實現介面的Aop方法給特定方法執行環繞增強,並在產生異常的情況下進行提示

2.步驟:新增log4j.propertiessrc下,以及log4j-1.2.17.jar新增lib

3.實現類實現介面用來定義

1. public class AroundLogger implements MethodInterceptor {  

2.     private static final Logger log = Logger.getLogger(AroundLogger.class);  

3.   

4.     public Object invoke(MethodInvocation arg0) throws Throwable {  

5.         Object target = arg0.getThis(); // 獲取被代理物件  

6.         Method method = arg0.getMethod(); // 獲取被代理方法  

7.         Object[] args = arg0.getArguments(); // 獲取方法引數  

8.         log.info("呼叫 " + target + " 的 " + method.getName() + " 方法。方法入參:"  

9.                 + Arrays.toString(args));  

10.         try {  

11.             Object result = arg0.proceed(); // 呼叫目標方法,獲取目標方法返回值  

12.             log.info("呼叫 " + target + " 的 " + method.getName() + " 方法。方法返回值:"  

13.                     + result);  

14.             return result;  

15.         } catch (Throwable e) {  

16.             log.error(method.getName() + " 方法發生異常:" + e);  

17.             throw e;  

18.         }  

19.     }  

20. }  

4.Spring容器配置

1. <bean id="aroundLogger" class="aop.AroundLogger"></bean>  

2. <aop:config>  

3.     <aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" />  

4.     <aop:advisor pointcut-ref="pointcut" advice-ref="aroundLogger" />  

5. </aop:config>  

==================================================

例三:特定異常增強---註解

1.使用註解的Aop方式實現異常增強

2.方法中

1. @Aspect  

2. public class ErrorLogger {  

3.     private static final Logger log = Logger.getLogger(ErrorLogger.class);  

4.     @AfterThrowing(pointcut = "execution(* biz.IUserBiz.*(..))", throwing = "e")  

5.     public void afterThrowing(JoinPoint jp, RuntimeException e) {  

6.         log.error(jp.getSignature().getName() + " 方法發生異常:" + e);  

7.     }  

8. }  

3.Spring容器配置

<bean class="aop.ErrorLogger"></bean>

<aop:aspectj-autoproxy />

==================================================

例四:環繞增強---註解

1.使用註解方式實現環繞增強

2.

1. @Aspect  

2. public class AroundLogger {  

3.     private static final Logger log = Logger.getLogger(AroundLogger.class);  

4.     @Around("execution(* biz.IUserBiz.*(..))")  

5.     public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {  

6.         log.info("呼叫 " + jp.getTarget() + " 的 " + jp.getSignature().getName()   

7.                 + " 方法。方法入參:" + Arrays.toString(jp.getArgs()));  

8.         try {   Object result = jp.proceed();  

9.             log.info("呼叫 " + jp.getTarget() + " 的 "   

10.             + jp.getSignature().getName() + " 方法。方法返回值:" + result);  

11.             return result;  

12.         } catch (Throwable e) {  

13.     log.error(jp.getSignature().getName() + " 方法發生異常:" + e);  

14.     throw e; }  

15.     }   }  

3.註解方式的前置後置以及最終增強型別

1. @Aspect  

2. public class AfterLogger {  

3.     private static final Logger log = Logger.getLogger(AfterLogger.class);  

4.     @After("execution(* biz.IUserBiz.*(..))")  

5.     public void afterLogger(JoinPoint jp) {  

6.         log.info(jp.getSignature().getName() + " 方法結束執行。");  

7.     }  

8. }  

1. @Aspect  

2. public class UserBizLogger {  

3.     private static final Logger log = Logger.getLogger(UserBizLogger.class);  

4.       

5.     @Before("execution(* biz.IUserBiz.*(..))")  

6.     public void before() {  

7.         log.info("即將呼叫業務方法");  

8.     }  

9.       

10.     @AfterReturning("execution(* biz.IUserBiz.*(..))")  

11.     public void afterReturning() {  

12.         log.info("業務方法呼叫完畢");  

13.     }  

14.   

15. }  

==================================================

例五:環繞增強-----schema方式

1.使用註解方式實現環繞增強

1. public class AroundLogger {  

2.     public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable { … }   

3. }  

1. <bean id="theLogger" class="aop. AroundLogger"></bean>  

2. <aop:config>  

3.     <aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" />  

4.     <aop:aspect ref="theLogger">  

5.         <aop:around  method="aroundLogger"  pointcut-ref="pointcut" />  

6.     </aop:aspect>  

7. </aop:config>  

==================================================

例六:最終增強-----schema方式

1. public class AfterLogger {  

2.     public void afterLogger(JoinPoint  jp) { … }  

3. }  

1. <bean id="theLogger" class="aop. AfterLogger"></bean>  

2. <aop:config>  

3.     <aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" />  

4.     <aop:aspect ref="theLogger">  

5.         <aop:after  method="afterLogger"  pointcut-ref="pointcut" />  

6.     </aop:aspect>  

7. </aop:config>  

.