Spring面向切面编程的三种方式以及常用相关案例总结

本文介绍 Spring 面向切面编程(AOP)的三种实现方式:接口方式、注解方式及 Schema 方式,并通过具体示例展示了如何进行执行前、后、异常等增强操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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>  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值