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>  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
面向方面的编程技术(AOP)是一种编程范式,它通过将应用程序的主要业务逻辑与横切关注点(如日志记录、安全性、性能等)分离来提高代码的模块化性、可重用性和可维护性。本文将介绍AOP的概念、原理、应用和实现,以及AOP在实际项目中的应用案例。 一、AOP的概念和原理 AOP是一种基于切面(Aspect)的编程技术,它将应用程序的主要业务逻辑与横切关注点分离。切面是横跨多个对象的功能,例如日志记录、性能统计、事务管理等。利用AOP,可以将这些关注点模块化,并通过声明式编程的方式插入到应用程序的主要业务逻辑中,从而实现代码的重用和可维护性的提高。 AOP的核心原理是动态代理。在运行时,AOP框架会动态生成代理对象,并将切面织入到代理对象中。当客户端调用代理对象的方法时,代理对象会拦截该方法的调用,并执行与该方法相关切面代码,最后再将控制权交给原始对象。通过这种方式,AOP实现了业务逻辑的分离和切面的模块化。 二、AOP的应用 AOP的应用领域非常广泛,特别是在企业级应用程序开发中。下面是AOP的几个常见应用场景: 1. 日志记录:将日志记录作为一个切面,可以在应用程序的任何地方记录日志,从而方便开发人员进行调试和故障排除。 2. 安全性:将安全性作为一个切面,可以在应用程序的任何地方实施安全性控制,从而保护应用程序的机密信息和敏感操作。 3. 性能:将性能作为一个切面,可以在应用程序的任何地方监控和优化性能,从而提高应用程序的响应速度和吞吐量。 4. 事务管理:将事务管理作为一个切面,可以在应用程序的任何地方实现事务控制,从而保证数据的一致性和可靠性。 三、AOP的实现 AOP的实现方式有两种:静态AOP和动态AOP。 静态AOP是通过编译器或预处理器实现的,它将切面织入到应用程序的字节码中。这种方式的优点是执行效率高,缺点是不够灵活,无法支持动态织入。 动态AOP是通过运行时代理实现的,它将切面织入到代理对象中。这种方式的优点是灵活性高,能够支持动态织入,缺点是执行效率相对较低。 目前比较流行的AOP框架有Spring AOP和AspectJ。Spring AOP是基于代理的动态AOP框架,它支持方法拦截和环绕通知等多种切面类型。AspectJ是基于字节码的静态AOP框架,它支持更多的切面类型,例如前置通知、后置通知、异常通知和最终通知等。 四、AOP的实际应用案例 下面是AOP在实际项目中的应用案例: 1. 日志记录:在一个电商网站中,通过AOP实现了对用户登录、购物车操作、订单提交等关键操作的日志记录。通过这种方式,可以方便地跟踪和分析用户的操作行为。 2. 安全性:在一个财务系统中,通过AOP实现了对敏感操作的安全性控制,例如只有经过授权的用户才能访问财务数据,不能将数据外传等。 3. 性能:在一个电商网站中,通过AOP实现了对数据库访问的性能监控和优化,例如使用缓存、优化SQL语句等。 4. 事务管理:在一个订单管理系统中,通过AOP实现了对订单状态的事务控制,例如在订单提交成功后,将订单状态从“待付款”改为“已付款”,并更新库存等。 总之,AOP是一种非常有用的编程技术,它可以提高代码的模块化性、可重用性和可维护性,同时也能够简化开发人员的工作和提高应用程序的质量。在实际项目中,我们可以根据具体的需求选择合适的AOP框架和切面类型,从而实现业务逻辑的分离和切面的模块化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值