开发配置:Eclipse + jdk 1.8 + Tomcat 7.0
Spring AOP自身也有一个实现aop的框架,但这里使用的是AspectJ来实现aop。
使用AspectJ来实现aop有两种方法,一种是注解的方式,另一种是xml的方式,这里说的是基于xml的方式。
知道了基于注解的aop后,理解xml配置会更容易,Spring 使用AspectJ 实现 AOP(基于注解)
AOP有五种通知,分别是
@Befor:前置通知,在方法执行之前执行 @After:后置通知,在方法执行之后执行 @AfterRunning:返回通知,在方法返回结果之后执行 @AfterThrowing:异常通知,在方法抛出异常之后执行 @Around:环绕通知,围绕着方法执行
项目结构:
一、需要的jar包:
这三个是AspectJ的jar包:aopalliance-1.0.jar
aspectjweaver-1.9.0.jar
spring-aspects-4.3.8.RELEASE.jar
这些事spring的核心包:
commons-logging-1.2.jar
spring-aop-4.3.8.RELEASE.jar
spring-beans-4.3.8.RELEASE.jar
spring-context-4.3.8.RELEASE.jar
spring-core-4.3.8.RELEASE.jar
spring-expression-4.3.8.RELEASE.jar
二、bean-xml.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <!-- 扫描com.qw.apo.impl包及其子包下面的所有的类的注解 --> <context:component-scan base-package="com.qw.aop.xml"/> <!-- 配置AOP --> <aop:config> <!-- 配置切点表达式,可以定义多个,只要id不同就可以 --> <aop:pointcut expression="execution(* com.qw.aop.xml.AtithmeticCalculator.*(int, int))" id="pointcut"/> <!-- 配置切面及通知,可以定义多个切面 --> <aop:aspect ref="loggingAspect" order="2"><!-- ref:指向切面 order:切面的优先级,越小优先级又高 --> <!-- 前置通知 method:切面里面的方法 pointcut-ref:使用的切点表达式--> <aop:before method="beforeMethod" pointcut-ref="pointcut"/> <!-- 后置通知 --> <aop:after method="afterMethod" pointcut-ref="pointcut"/> <!-- 返回通知 returning:返回的值,与方法中的返回值一样--> <aop:after-returning method="afterRunning" pointcut-ref="pointcut" returning="result"/> <!-- 异常通知 throwing:抛出异常,与方法中一样--> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="ex"/> <!-- 环绕通知,很少用 --> <aop:around method="around" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
三、接口类、接口实现类、切面类、测试类
接口类:AtithmeticCalculator
package com.qw.aop.xml; public interface AtithmeticCalculator { int add(int i,int j); int sub(int i,int j); int div(int i,int j); }
接口实现类:AtithmeticCalculatorImpl
package com.qw.aop.xml; import org.springframework.stereotype.Component; @Component public class AtithmeticCalculatorImpl implements AtithmeticCalculator { @Override public int add(int i, int j) { int result = i + j; return result; } @Override public int sub(int i, int j) { int result = i - j; return result; } @Override public int div(int i, int j) { int result = i / j; return result; } }
切面类:LoggingAspect
package com.qw.aop.xml; import java.util.Arrays; import java.util.List; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.stereotype.Component; @Component public class LoggingAspect { public void beforeMethod(JoinPoint joinPoint){ //执行的方法名 String methodName = joinPoint.getSignature().getName(); //执行的方法的参数 List<Object> args = Arrays.asList(joinPoint.getArgs()); //执行的方法所在的类的名称 String className = joinPoint.getTarget().getClass().getName(); System.out.println("前置通知,执行的方法名:"+ methodName + ",方法的参数:"+ args + ",方法所在的类名:" + className); } public void afterMethod(JoinPoint joinPoint){ //执行的方法名 String methodName = joinPoint.getSignature().getName(); //执行的方法的参数 List<Object> args = Arrays.asList(joinPoint.getArgs()); System.out.println("后置通知,执行的方法名:"+ methodName + ",方法的参数:"+ args); } public void afterRunning(JoinPoint joinPoint,Object result){ //执行的方法名 String methodName = joinPoint.getSignature().getName(); //执行的方法的参数 List<Object> args = Arrays.asList(joinPoint.getArgs()); System.out.println("返回通知,执行的方法名:"+ methodName + ",方法的参数:"+ args +",返回值是:"+result); } public void afterThrowing(JoinPoint joinPoint,Exception ex){ //执行的方法名 String methodName = joinPoint.getSignature().getName(); //执行的方法的参数 List<Object> args = Arrays.asList(joinPoint.getArgs()); System.out.println("异常通知,执行的方法名:"+ methodName + ",方法的参数:"+ args + ",异常:"+ex); } public Object around(ProceedingJoinPoint pjd){ Object result = null; try { //前置通知 System.out.println("前置通知:"+pjd.getSignature().getName()); //执行目标方法 result = pjd.proceed(); //返回通知 System.out.println("返回通知:"+pjd.getSignature().getName()); } catch (Throwable e) { //异常通知 System.out.println("异常通知:"+pjd.getSignature().getName() + ",异常:" + e); throw new RuntimeException(e); } //后置通知 System.out.println("后置通知:"+pjd.getSignature().getName()); return result; } }
测试类:Main
package com.qw.aop.xml; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("bean-xml.xml"); AtithmeticCalculator calculator = context.getBean(AtithmeticCalculator.class); int result = calculator.add(1, 4); System.out.println("result:"+result); result = calculator.sub(1, 4); System.out.println("result:"+result); result = calculator.div(1, 1); System.out.println("result:"+result); } }
源码,关于Spring 使用AspectJ实现AOP的基于注解和基于xml文件的,都在
https://download.csdn.net/download/java_xuetu/10358660