SpringBoot 利用aspectJ进行AOP切面管理

Java是面向对象编程,Java AOP是面向切面编程,最近学习该部分内容知识,讲学习心得在这里做一个整理,以帮助后续学习以及使用。

首先什么事AOP?个人理解,在开发过程中,又核心业务,也有非核心业务。例如一个登陆功能,在登录功能中核心业务是进行登陆操作,继判断用户是否在数据库中存在;同事也有一些非核心业务,如日志记录,参数校验等。模块化开发思想,将这三部分模块进行分开处理,从而不会使得代码冗余,方便维护。但是模块分开之后,我所需要的效果还是要包含校验,日志和登录。AOP所处理的,就是将这三部分内容按照一定的规则组合起来。如下图:

SpringBoot 利用aspectJ进行AOP切面管理_第1张图片

AOP的底层核心,就是Java的动态代理机制,AOP中有几个很重要的概念,整理如下表:

横切关注点 从每个方法中抽取出来的同一类非核心业务
切面(Aspect) 横切关注点的分装类,每个关注点体现为一个通知
通知Advice 具体的方法
目标 目标对象
代理 向目标对象应用通知之后创建的代理对象
连接点JoinPoint 横切关注点在程序代码中的具体体现,对应程序执行的某个特定位置,例如:类某个方法调用前、调用后、方法捕获到异常后等。

Spring为开发者提供了自己的一套AOP框架。但实际开发过程中,使用最多的还是AspectJ框架,该框架是目前最为流行的AOP框架,在Spring2.0开始,支持注解和XML配置文件两种方式进行配置使用。

AspectJ提供了5种类型的通知注解,常用的如下表:

@Before 前置通知,在方法执行前执行
@After 后置通知,在方法执行后执行
@AfterRunning 返回通知,在方法返回结果后返回,可以利用returning属性,接收方法的返回结果
@AfterThrowing 异常通知

 

其中每一个注解,都需要指定一个execution,继改切面作用在哪一个方法之中,样例如下:

@Before(value = "execution(* com.springboot.aspectj.springboot_aspect.service.*.*(..))")

其中execution表达式中每一个字符解释如下图:

SpringBoot 利用aspectJ进行AOP切面管理_第2张图片

下面以SpringBoot,结合Aspect做一个示例。首先简单的业务需求,有一个add方法,有两个int类型的参数相加,返回结果。

1、首先pom引入AOP的maven依赖


     org.springframework.boot
     spring-boot-starter-aop

2、编写切面类

/**
 * 切面
 */
@Configuration
@Aspect
public class MyAspectJ {
    /**
     * @Before 前置通知
     * @param joinPoint
     */
    @Before(value = "execution(* com.springboot.aspectj.springboot_aspect.service.*.*(..))")
    public void before(JoinPoint joinPoint){
        String MethodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("before MethodName:"+MethodName+",argNames:"+ Arrays.toString(args));
    }

    /**
     * @After后置通知
     * @param joinPoint
     */
    @After(value = "execution(* com.springboot.aspectj.springboot_aspect.service.*.*(..))")
    public void after( JoinPoint joinPoint){
        String MethodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("after MethodName:"+MethodName+",argNames:"+ Arrays.toString(args));
    }

    /**
     * @AfterReturning返回通知
     * @param joinPoint
     * @param result
     */
    @AfterReturning(value = "execution(* com.springboot.aspectj.springboot_aspect.service.*.*(..))",returning = "result")
    public void result(JoinPoint joinPoint,Object result){
        String MethodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("AfterReturning MethodName:"+MethodName+",argNames:"+ Arrays.toString(args)+",result:" + result);
    }

}

3、编写一个目标类,实现具体的核心业务:

public interface CalcService {

    public int add(int a,int b);
}


@Service
public class CalcServiceImpl implements CalcService {
    @Override
    public int add(int a, int b) {
        int result = a + b;
        System.out.println("a:"+a+",b:"+b+",result:"+result);
        return result;
    }
}

4、编写测试类,查看运行结果

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

    @Autowired
    private CalcService calcService;
    @Test
    public void contextLoads() {
        calcService.add(1,2);
    }

}



//结果
before MethodName:add,argNames:[1, 2]
a:1,b:2,result:3
after MethodName:add,argNames:[1, 2]
AfterReturning MethodName:add,argNames:[1, 2],result:3

以上就是自己的一些整理心得,如有不对之处,还请大家指出,谢谢

你可能感兴趣的:(springboot,AOP)