Spring AOP -- 使用 Aspectj

Spring AOP – 使用 Aspectj

        使用 Aspectj 注解实现各种通知

@Before:前置通知,在方法执行前执行
@After:后置通知,在方法执行后通知
@AfterRunning:返回通知,在方法返回结果后通知
@AfterThrowing:异常通知:在方法抛出异常后通知
@Around:环绕通知:围绕着方法执行

需要以下jar包

		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectjrt.version}</version>
        </dependency>

创建接口与实现类,并交给 Spring 管理

public interface ArithmeticCalculator {
    int add(int i, int j);
    int div(int i, int j);
}
@Component
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

    @Override
    public int add(int i, int j) {
        int result = i + j;
        System.out.println("result:" + result);
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result = i / j;
        System.out.println("result:" + result);
        return result;
    }
}

在Spirng配置里加入:

<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.java.spring.aop"></context:component-scan>

      使用 Aspectj 注解来实现前置通知

//把该类声明为一个切面:需要先将类放入到 IOC 容器中 ,再声明为一个切面
@Aspect
@Component
public class Logging {
    /*
        声明该方法是一个 前置通知:在目标方法开始前执行
        execution(* com.java.spring.aop.impl.*.*()) 中表示任意修饰符,任意返回值,
        在com.java.spring.aop.impl 包下任意类中的任意方法
     */
    @Before("execution(* com.java.spring.aop.impl.*.*(int,int))")
    //可以在方法里声明类型为 JoinPoint 的参数,获得连接点的细节,如方法名称和参数值
    public void beforLogin(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName(); //获取方法名称
        List<Object> args = Arrays.asList(joinPoint.getArgs()); //获取方法参数值

        System.out.println("method " + methodName + " begins " + args);
    }
}

      执行结果如下

 method add begins [3, 6]
 result:9
 method div begins [12, 3]
 result:4

      使用 Aspectj 注解来实现后置通知

//在方法执行后,执行通知(无论是否发送异常)
    @After("execution(* com.java.spring.aop.impl.*.*(int,int))")
    public void afterLogin(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();

        System.out.println("method " + methodName);
    }

      执行结果如下

 result:9
 method add end 
 result:4
 method div end 

注意:即便发生异常,依然会执行:
在这里插入图片描述

      使用 Aspectj 注解来实现返回通知

	//在方法正常结束后执行,可以访问到方法的返回值
    @AfterReturning(value = "execution(* com.java.spring.aop.impl.*.*(int,int))",returning = "result")
    public void afterReturningLogin(JoinPoint joinPoint , Object result){
        String methodName = joinPoint.getSignature().getName();

        System.out.println("method " + methodName+" result " + result);
    }

      执行结果如下

result:9
method add result 9
result:4
method div result 4

      使用 Aspectj 注解来实现异常通知

//在方法出现异常时执行,可以访问到异常对象,且可以指定特定异常在执行通知
    @AfterThrowing(value = "execution(* com.java.spring.aop.impl.*.*(int,int))",throwing = "ex")
    public void afterThrowingLogin(JoinPoint joinPoint , Exception ex){
        String methodName = joinPoint.getSignature().getName();

        System.out.println("method " + methodName+" exception " + ex);
    }

      执行结果如下
在这里插入图片描述

      使用 Aspectj 注解来实现环绕通知

/*
    环绕通知需要有 ProceedingJoinPoint 这个参数,这个参数可以决定是否执行目标方法
    环绕通知必须有返回值,返回值为目标方法返回值
     */

    @Around("execution(* com.java.spring.aop.impl.*.*(int,int))")
    public Object aroundLogin(ProceedingJoinPoint pjd ){

        Object result = null;
        String methodName = pjd.getSignature().getName();

        try {
            //前置通知
            System.out.println("method " + methodName + " begins " + Arrays.asList(pjd.getArgs()));
            //执行目标方法
            result = pjd.proceed();
            //返回通知
            System.out.println("method " + methodName+" result " + result);
        } catch (Throwable e) {
            //异常通知
            System.out.println("method " + methodName+" exception " + e);
        }
        //后置通知
        System.out.println("method " + methodName+" end ");
        return result;
    }

      执行结果如下
在这里插入图片描述
      发生异常后如下
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章