SPRING学习(十九)--基于注解的AOP切面编程
Posted GLLegolas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPRING学习(十九)--基于注解的AOP切面编程相关的知识,希望对你有一定的参考价值。
上篇中介绍了基于XML配置的AOP切面编程,除了XML配置AOP切面编程外,还可以通过注解方式实现AOP切面编程,本篇通过一个小例子来介绍基于注解的AOP编程。
1、在spring中使用AOP变成,不止要导入spring-aop.jar,还需要导入spring-aspects.jar、aspectjweaver.jar和aopalliance.jar,但是aspectjweaver.jar被spring-aspects.jar依赖,aopalliance.jar被spring-aop.jar依赖,spring-aop.jar又被spring-mvc.jar依赖,所以只要导入spring-mvc.jar和spring-aspects.jar就行了。
2、spring-aop-annotion.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置自动扫描的包 --> <context:component-scan base-package="springAopAnnotion"></context:component-scan> <!-- 自动为切面方法中匹配的方法所在的类生成代理对象。 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
3、被增强的类Sleep.java
package springAopAnnotion; import org.springframework.stereotype.Component; //将实现类加入Spring的IOC容器进行管理 @Component("sleeping") public class Sleep { public void sleep(String who){ System.out.println(who + " want to sleep!"); } }
4、增强类SleepAspect.java
package springAopAnnotion; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; /** * * 有两种声明切入点方法 * 1、提前声明切入点@PointCut,后续在切入方法中引用切入点 * 2、直接在切入方法中声明切入点 * * 切入方式一共有五种 * 1、方法执行前 @before * 2、方法执行后,返回前 @after * 3、方法返回后 @afterReturning * 4、方法执行前后 @around * 5、抛异常时候 @AfterThrowing * @author qiaozhong */ @Component @Aspect public class SleepAspect { /** * 提前声明切入点@PointCut,后续在切入方法中引用切入点 * 声明方法执行前的切点 */ @Pointcut("execution(* springAopAnnotion.Sleep.*(..))") public void beforeMethod(){} /** * 提前声明切入点@PointCut,后续在切入方法中引用切入点 * 声明方法执行后的切点 */ @Pointcut("execution(* springAopAnnotion.Sleep.*(..))") public void afterMethod(){} /** * 方法执行前,要织入的切面方法,切入点为之前声明的beforeMethod() * @param joinPoint */ @Before("beforeMethod()") public void beforeAspect(JoinPoint joinPoint){ System.out.println("方法执行前,入参="+joinPoint.getArgs()[0]); } /** * 方法执行后,返回前,要织入的切面方法,切入点为之前声明的afterMethod() * @param joinPoint */ @After("afterMethod()") public void afterAspect(){ System.out.println("方法执行后"); } /** * 方法返回后,要织入的切面方法,切入点在本方法中直接配置 * @param joinPoint */ @AfterReturning(value="execution(* springAopAnnotion.Sleep.*(..))") public void afterReturnAspect(){ System.out.println("方法返回后"); } /** * 异常通知:目标方法发生异常的时候执行以下代码,切入点在本方法中直接配置 */ @AfterThrowing(value="execution(* springAopAnnotion.Sleep.*(..))",throwing="e") public void afterThorwingMethod(JoinPoint jp, NullPointerException e){ String methodName = jp.getSignature().getName(); System.out.println("【异常通知】the method 【" + methodName + "】 occurs exception: " + e); } /** * 环绕通知:目标方法执行前后分别执行一些代码,发生异常的时候执行另外一些代码,切入点在本方法中直接配置 * @return */ @Around(value="execution(* springAopAnnotion.Sleep.*(..))") public void aroundMethod(ProceedingJoinPoint jp) { try { System.out.println("aroundMethod前置切面"); jp.proceed(); System.out.println("aroundMethod后置切面"); } catch (Throwable e) { e.printStackTrace(); } } }
5、测试类
package springAopAnnotion; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSleep { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("springConfig/spring-aop-annotion.xml"); Sleep sleep = (Sleep)ac.getBean("sleeping"); sleep.sleep("Little ball"); } }
结果:
aroundMethod前置切面 方法执行前,入参=Little ball Little ball want to sleep! aroundMethod后置切面 方法执行后 方法返回后
以上是关于SPRING学习(十九)--基于注解的AOP切面编程的主要内容,如果未能解决你的问题,请参考以下文章