【Spring注解驱动开发】你敢信?面试官竟然让我现场搭建一个AOP测试环境!

28 阅读3分钟
  • 后置通知(@After):在目标方法运行结束之后运行,不管是正常结束还是异常结束都会执行。

  • 返回通知(@AfterReturning):在目标方法正常返回之后运行。

  • 异常通知(@AfterThrowing):在目标方法抛出异常后运行。

  • 环绕通知(@Around):动态代理,手动推进目标方法运行。

综上,LogAspect类中的具体方法定义如下所示。

package io.mykit.spring.plugins.register.aspect;

import org.aspectj.lang.annotation.*;

/**

  • @author binghe

  • @version 1.0.0

  • @description 打印日志的切面类

*/

@Aspect

public class LogAspect {

@Pointcut("execution(public int io.mykit.spring.plugins.register.aop.MathHandler.*(..))")

public void pointCut(){

}

@Before("pointCut()")

public void logStart(){

System.out.println("加法运行开始,参数列表是:{}");

}

@After("pointCut()")

public void logEnd(){

System.out.println("加法运行结束");

}

@AfterReturning("pointCut()")

public void logReturn(){

System.out.println("加法正常返回,运行结果:{}");

}

@AfterThrowing("pointCut()")

public void logException(){

System.out.println("加法异常,异常信息:{}");

}

}

  • logStart()方法:MathHandler类的add()方法运行之前运行。

  • logEnd()方法:MathHandler类的add()方法运行结束之后运行。

  • logReturn()方法:MathHandler类的add()方法正常返回之后运行。

  • logException()方法:MathHandler类的add()方法抛出异常后执行。

4.将目标类和切面类加入到IOC容器

io.mykit.spring.plugins.register.config包中,新建AopConfig类,并使用@Configuration注解标注这是一个Spring的配置类,同时使用@EnableAspectJAutoProxy注解开启基于注解的AOP模式。在AopConfig类中,使用@Bean注解将MathHandler类和LogAspect类加入到IOC容器中,如下所示。

package io.mykit.spring.plugins.register.config;

import io.mykit.spring.plugins.register.aop.MathHandler;

import io.mykit.spring.plugins.register.aspect.LogAspect;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**

  • @author binghe

  • @version 1.0.0

  • @description 测试AOP

*/

@Configuration

@EnableAspectJAutoProxy

public class AopConfig {

@Bean

public MathHandler mathHandler(){

return new MathHandler();

}

@Bean

public LogAspect logAspect(){

return new LogAspect();

}

}

5.创建测试类

io.mykit.spring.test包中创建AopTest测试类,并在AopTest类中创建testAop01()方法,如下所示。

package io.mykit.spring.test;

import io.mykit.spring.plugins.register.aop.MathHandler;

import io.mykit.spring.plugins.register.config.AopConfig;

import org.junit.Test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**

  • @author binghe

  • @version 1.0.0

  • @description 测试切面

*/

public class AopTest {

@Test

public void testAop01(){

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);

MathHandler mathHandler = context.getBean(MathHandler.class);

mathHandler.add(1, 2);

context.close();

}

}

运行AopTest类中的testAop01()方法,输出的结果信息如下所示。

加法运行开始,参数列表是:{}

目标方法执行

加法运行结束

加法正常返回,运行结果:{}

可以看到,执行了切面类中的方法,并打印出了相关信息。但是没有打印参数列表和运行结果。

6.在切面类中打印参数列表和返回结果

那如果需要打印出参数列表和运行结果,该怎么办呢?别急,我们继续往下看。

要想打印出参数列表和运行结果,就需要对LogAspect类中的方法进行优化,优化后的结果如下所示。

package io.mykit.spring.plugins.register.aspect;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.*;

import java.util.Arrays;

/**

  • @author binghe

  • @version 1.0.0

  • @description 打印日志的切面类

*/

@Aspect

public class LogAspect {

@Pointcut("execution(public int io.mykit.spring.plugins.register.aop.MathHandler.*(..))")

public void pointCut(){

}

@Before("pointCut()")

public void logStart(JoinPoint joinPoint){

System.out.println(joinPoint.getSignature().getName() + " 运行开始,参数列表是:{"+ Arrays.asList(joinPoint.getArgs()) +"}");

}

@After("pointCut()")

public void logEnd(JoinPoint joinPoint){

System.out.println(joinPoint.getSignature().getName() + " 运行结束");

}

@AfterReturning(value = "pointCut()", returning = "result")

public void logReturn(JoinPoint joinPoint, Object result){

System.out.println(joinPoint.getSignature().getName() + " 正常返回,运行结果:{"+result+"}");

}

@AfterThrowing(value = "pointCut()", throwing = "exception")

public void logException(JoinPoint joinPoint, Exception exception){

System.out.println(joinPoint.getSignature().getName() + " 异常,异常信息:{"+exception+"}");

}

}

这里,需要注意的是:JoinPoint参数一定要放在参数的第一位。

此时,我们再次运行AopTest类中的testAop01()方法,输出的结果信息如下所示。

add 运行开始,参数列表是:{[1, 2]}

目标方法执行

add 运行结束

add 正常返回,运行结果:{3}

7.目标方法抛出异常

我们在MathHandler类的add()方法中抛出一个异常,来测试下异常情况,如下所示。

package io.mykit.spring.plugins.register.aop;

/**

  • @author binghe

  • @version 1.0.0

  • @description 定义一个数据处理器类,用于测试AOP

*/

public class MathHandler {

public int add(int i, int j){

System.out.println("目标方法执行");

throw new RuntimeException();

//return i + j;

}

}

此时,我们再次运行AopTest类中的testAop01()方法,输出的结果信息如下所示。

img img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

开源项目:docs.qq.com/doc/DSlVlZExWQ0FRSE9H