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.properties在src下,以及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.properties在src下,以及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>
.