spring aop如何在切面类中获取切入点相关方法的参数、方法名、返回值、异常等信息

aop思想可以很好的帮助我们实现代码的解耦,比如我们之前提到的,将日志代码与业务层代码完全独立,通过spring aop的代理类进行整合。在切面类中,我们也能够通过spring提供的接口,很好的获取原切入点的相关信息。

首先,我们还是从代码着手

业务层代码StudentServiceImpl

@Service("studentService")
public class StudentServiceImpl implements StudentService {


    @Override
    public int addStudent(Student student) throws Exception {
            System.out.println("addStudent...业务层代码执行...");
            return 1;
    }

    @Override
    public int deleteStudent(Integer id) throws Exception{

            System.out.println("deleteStudent...业务层代码执行...");
            int i = 1/0;
            return 0;

    }
}

切面类StudentServiceLogger

@Aspect
@Component
public class StudentServiceLogger {

    @Before("execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )")
    public void doBefore(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法执行前...");
        System.out.println("参数为:"+ Arrays.asList(args));
    }

    @After("execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )")
    public void doAfter(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法执行后...");
    }

    @AfterReturning(value = "execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )" , returning = "returning")
    public void doReturn(JoinPoint joinPoint,Object returning){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法返回,返回值为:"+returning);

    }

    @AfterThrowing(value = "execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )",throwing = "ex")
    public void doThrow(JoinPoint joinPoint,Exception ex){
        String methodName = joinPoint.getSignature().getName();
        System.out.println(methodName+"方法异常,异常信息为:"+ex.getMessage());
    }

}

测试类AopTest

public class AopTest {

    ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

    @Test
    public void test1() throws Exception {
        StudentService studentService = ac.getBean("studentService",StudentService.class);
        studentService.addStudent(new Student());
        System.out.println("==================割===============");
        studentService.deleteStudent(1);

    }
}

最后是日志输出结果

addStudent方法执行前...
参数为:[com.wuwl.domain.Student@7e5c856f]
addStudent...业务层代码执行...
addStudent方法执行后...
addStudent方法返回,返回值为:1
==================割===============
deleteStudent方法执行前...
参数为:[1]
deleteStudent...业务层代码执行...
deleteStudent方法执行后...
deleteStudent方法异常,异常信息为:/ by zero

关于切入点方法的相关信息,spring很好的封装在了org.aspectj.lang.JoinPoint接口中,这里需要注意的是,在org.aopalliance.intercept包下,也有这样命名的一个接口,千万不要搞错了。
joinPoint.getArgs()方法可以返回切入方法的参数信息,返回值为一个数组,遍历即可获取;joinPoint.getSignature()方法的返回值为方法签名,签名接口中就包括方法名之类的信息。
如果需要在通知方法中获取切入方法的返回值,或者异常信息,则需要使用到对应注解的对应属性才行。点开@AfterReturning注解可以看到一个String returning() default "";属性,在通知方法中添加返回值参数,然后再注解中声明该参数为切入方法的返回值即可,操作方法可参考上面的代码。同理可以,使用@AfterThrowing注解的String throwing() default "";属性,可以获取到切入方法抛出的异常信息。

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