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>
pox.xml

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 }
AtithmeticCalculator

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 }
AtithmeticCalculatorImpl

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 }
LoggingAspect

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>
applicationContext.xml

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 }
applicationContext.xml

 

  

posted @ 2017-09-11 22:45  Limo1996  阅读(681)  评论(0)    收藏  举报