SpringAop简单案例-基于注解

SpringAop简单案例

1) Aop相关配置类

package com.example.study.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component  // 必须加该注解,否则无效
public class MyAspect {

//    @Pointcut("@annotation(com.example.study.annotation.ProxyAnno)")  //基于注解
    @Pointcut("execution(* com.example.study.aop.MyService.*(..))")     //基于表达式
    public void pointcut(){
        System.out.println("切入点: @ProxyAnno");
    }


    @Around(value = "pointcut()")
    public Object doAroudAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("切面环绕通知开始: Around.beg");
        Object obj = null;
        try{
            // 执行方法
            proceedingJoinPoint.proceed();
        }catch (Throwable t){
            System.out.println("切面环绕通知异常catch: Around.catch");
            throw t;
        } finally {
            System.out.println("切面环绕通知异常finally: Around.finally");
        }
        System.out.println("切面环绕通知结束: Around.end");
        return obj;
    }

    @Before(value = "pointcut()")
    public void doBeforeAdvice(JoinPoint point){
        System.out.println("方法执行前: Before");
        Object[] args = point.getArgs(); // 参数
        String name = point.getSignature().getName(); // 方法名
        System.out.println("方法执行前: args["+args+"];name["+name+"]");
    }

    @After(value = "pointcut()")
    public void doAfterAdvice(JoinPoint point){
        System.out.println("方法执行后: After");
        Object[] args = point.getArgs(); // 参数
        String name = point.getSignature().getName(); // 方法名
        System.out.println("方法执行后: args["+args+"];name["+name+"]");
    }

    @AfterReturning(value = "pointcut()",returning = "result")
    public void doAfterReturningAdvice(JoinPoint point,Object result){
        System.out.println("方法成功执行返回: AfterReturning");
        Object[] args = point.getArgs(); // 参数
        String name = point.getSignature().getName(); // 方法名
        System.out.println("方法成功执行返回: args["+args+"];name["+name+"];return["+result+"]");
    }

    @AfterThrowing(value = "pointcut()",throwing = "ex")
    public void doAfterReturningAdvice(JoinPoint point,Exception ex){
        System.out.println("方法执行异常: AfterThrowing");
        Object[] args = point.getArgs(); // 参数
        String name = point.getSignature().getName(); // 方法名
        System.out.println("方法执行异常: args["+args+"];name["+name+"];Exception["+ex+"]");
    }
}

2) 切面对象

package com.example.study.aop;

import com.example.study.annotation.ProxyAnno;
import org.springframework.stereotype.Component;

@Component
public class MyService{

    @ProxyAnno
    public String method(String name){
        System.out.println("=======执行方法========");
        return name;
    }

    @ProxyAnno
    public String methodException(String name){
        System.out.println("=======执行Exception方法========");
        int num = 1/0;
        return name;
    }
}

3) 测试类

package com.example.study.aop;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyAopTest {

    @Autowired
    private MyService myService;

    @Test
    public void aopTest(){
        /**
         * 执行结果如下:
         *  =======执行方法========
         * 结论:
         *  只有从springIoc容器中获取的bean,spring-aop才有效
         */
        MyService service = new MyService();
        service.method("test");
        System.out.println("=================new MyService.method=====================");

        /**
         * 执行结果如下:
         * 切面环绕通知开始: Around.beg
         * 方法执行前: Before
         * 方法执行前: args[[Ljava.lang.Object;@38a38ed4];name[method]
         * =======执行方法========
         * 方法成功执行返回: AfterReturning
         * 方法成功执行返回: args[[Ljava.lang.Object;@38a38ed4];name[method];return[test]
         * 方法执行后: After
         * 方法执行后: args[[Ljava.lang.Object;@38a38ed4];name[method]
         * 切面环绕通知异常finally: Around.finally
         * 切面环绕通知结束: Around.end
         *
         * 结论(执行顺序如下):
         *  around.beg->before->invoid->afterReturning->after->around.finally->around.end
         */
        myService.method("test");
        System.out.println("=================myService.method=====================");

        /**
         * 执行结果如下:
         * 切面环绕通知开始: Around.beg
         * 方法执行前: Before
         * 方法执行前: args[[Ljava.lang.Object;@515d615];name[methodException]
         * =======执行Exception方法========
         * 方法执行异常: AfterThrowing
         * 方法执行异常: args[[Ljava.lang.Object;@515d615];name[methodException];Exception[java.lang.ArithmeticException: / by zero]
         * 方法执行后: After
         * 方法执行后: args[[Ljava.lang.Object;@515d615];name[methodException]
         * 切面环绕通知异常catch: Around.catch
         * 切面环绕通知异常finally: Around.finally
         *
         * 结论(执行顺序如下):
         *  around.beg->before->invoid->AfterThrowing->after->around.catch->around.finally
         */
        try{
            myService.methodException("test");
        }catch (Exception e){

        }finally {
            System.out.println("=================myService.methodException=====================");
        }
    }
}


版权声明:本文为qq_43616689原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。