Spring AOP 使用注释(AspectJ)完成前置通知、后置通知、返回通知、异常通知的用法
小编用的是Intellij2017,用maven搭建了环境。
1.maven所用到的依赖如下
1 <!-- Spring需要 --> 2 <dependency> 3 <groupId>org.springframework</groupId> 4 <artifactId>spring-context</artifactId> 5 <version>4.3.9.RELEASE</version> 6 </dependency> 7 8 <!-- Spring需要 --> 9 <dependency> 10 <groupId>org.springframework</groupId> 11 <artifactId>spring-core</artifactId> 12 <version>4.3.7.RELEASE</version> 13 </dependency> 14 15 <!-- aspectj 的jar--> 16 <dependency> 17 <groupId>org.aspectj</groupId> 18 <artifactId>aspectjrt</artifactId> 19 <version>1.8.9</version> 20 </dependency> 21 22 <!-- aspectj 的jar--> 23 <dependency> 24 <groupId>org.aspectj</groupId> 25 <artifactId>aspectjtools</artifactId> 26 <version>1.8.9</version> 27 </dependency> 28 29 <!-- aspectj 的jar--> 30 <dependency> 31 <groupId>org.aspectj</groupId> 32 <artifactId>aspectjweaver</artifactId> 33 <version>1.7.4</version> 34 </dependency> 35 36 <!-- aop需要的jar--> 37 <dependency> 38 <groupId>org.springframework</groupId> 39 <artifactId>spring-aop</artifactId> 40 <version>4.3.9.RELEASE</version> 41 </dependency>
2.建立一个接口
1 package aop.impl; 2 3 public interface AtithmeticCalculator { 4 5 int add(int i, int j); 6 int sub(int i, int j); 7 int mul(int i, int j); 8 int div(int i, int j); 9 }
3.建立接口的实现类
注意:因为要切实现类中的方法,所以要将实现类加到IOC容器中(@Component)
1 package aop.impl; 2 3 import org.springframework.stereotype.Component; 4 5 @Component 6 public class AtithmeticCalculatorImpl implements AtithmeticCalculator { 7 public int add(int i, int j) { 8 int result = i + j; 9 return result; 10 } 11 12 public int sub(int i, int j) { 13 int result = i - j; 14 return result; 15 } 16 17 public int mul(int i, int j) { 18 int result = i * j; 19 return result; 20 } 21 22 public int div(int i, int j) { 23 int result = i / j; 24 return result; 25 } 26 }
4.建立一个类,实现横切的方法
注意:把这个类声明为切面,需要把类放到IOC容器中(@Component)、再声明为一个切面(@Aspect)
1 package aop.impl; 2 3 import org.aspectj.lang.JoinPoint; 4 import org.aspectj.lang.ProceedingJoinPoint; 5 import org.aspectj.lang.annotation.*; 6 import org.springframework.stereotype.Component; 7 8 import java.util.Arrays; 9 import java.util.List; 10 11 //把这个类声明为切面,需要把类放到IOC容器中、再声明为一个切面 12 @Aspect 13 @Component 14 class LoggingAspect { 15 //该方法是一个前置通知,在目标方法开始之前执行 16 @Before("execution(public int aop.impl.AtithmeticCalculator.*(int ,int ))") 17 public void beforeMethod(JoinPoint joinPoint) { 18 //获取当前执行的方法名 19 String methodName = joinPoint.getSignature().getName(); 20 //获取当前运行的对象 21 List<Object> args = Arrays.asList(joinPoint.getArgs()); 22 System.out.println("前置通知:The method" + methodName + " begins with " + args); 23 } 24 25 //后置通知:在目标方法执行后(无论是否发生异常),执行的通知 26 //在后置通知中还不能访问目标方法执行的结果 27 @After("execution(public int aop.impl.AtithmeticCalculator.*(int ,int ))") 28 public void afterMethod(JoinPoint joinPoint) { 29 //获取当前执行的方法名 30 String methodName = joinPoint.getSignature().getName(); 31 System.out.println("后置通知:The method " + methodName + " ends"); 32 } 33 34 //返回通知:在方法正常结束后反回的通知,可以访问到方法的返回值 35 @AfterReturning(value = "execution(public int aop.impl.AtithmeticCalculator.*(int ,int ))", 36 returning = "result") 37 public void afterReturning(JoinPoint joinPoint, Object result) { 38 String methodName = joinPoint.getSignature().getName(); 39 System.out.println("返回通知:The method " + methodName + " ends with " + result); 40 41 } 42 43 /** 44 * 在目标方法出现异常时会执行的代码 45 * 可以访问到异常对象;且可以指定在出现特定异常时在执行通知代码 46 * 47 * @param joinPoint 48 * @param ex 49 */ 50 //异常通知 51 @AfterThrowing(value = "execution(public int aop.impl.AtithmeticCalculator.*(int ,int ))", 52 throwing = "ex") 53 public void afterThrowing(JoinPoint joinPoint, Exception ex) { 54 String methodName = joinPoint.getSignature().getName(); 55 System.out.println("异常通知:The method " + methodName + " occurs exception: " + ex); 56 } 57 58 /** 59 * 环绕通知需要携带 ProceedingJoinPoint 类型的参数 60 * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint 类型的参数可以决定是否执行目标方法 61 * 且环绕通知必须有返回值,返回值必须为目标方法的返回值 62 */ 63 @Around("execution(public int aop.impl.AtithmeticCalculator.*(..))") 64 public Object aroundMethod(ProceedingJoinPoint pjd) { 65 Object result = null; 66 String methodName = pjd.getSignature().getName(); 67 //执行目标方法 68 try { 69 //前置通知 70 System.out.println("环绕通知(前置):The method " + methodName + " begins with " + Arrays.asList(pjd.getArgs())); 71 result = pjd.proceed(); 72 //后置通知 73 System.out.println("环绕通知(后置)The method ends with "+result); 74 } catch (Throwable e) { 75 e.printStackTrace(); 76 System.out.println("环绕通知(异常)The method ocuurs exception: " + e ); 77 throw new RuntimeException(e); 78 } 79 System.out.println("环绕通知(后置) The method ends"); 80 return result; 81 } 82 }
5.建立一个Bean
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 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"> 7 8 <!--配置自动扫描的包--> 9 <context:component-scan base-package="aop.impl" ></context:component-scan> 10 11 <!--使 AspjectJ 注释起作用:自动为匹配的类生成代理对象--> 12 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 13 </beans>
6.测试类
1 package aop.impl; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 public class Main { 7 public static void main(String args[]){ 8 //1.创建Spring的IOC容器 9 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 10 //2.从IOC容器中获取Bean的实例 11 AtithmeticCalculator atithmeticCalculator = context.getBean(AtithmeticCalculator.class); 12 //3.使用Bean 13 int result = atithmeticCalculator.add(3,6); 14 System.out.println("result:"+result); 15 16 result = atithmeticCalculator.mul(9,8); 17 System.out.println("result:"+result); 18 19 result = atithmeticCalculator.div(5,0); 20 System.out.println(result); 21 } 22 }


浙公网安备 33010602011771号