Spring注解驱动开发AOP功能

关于AOP的注解版开发可能大家都知道,本篇通过一个简单的demo来做入门的引导,其目的主要是分析SpringAOP的每一个阶段的核心源码帮我们做了些什么,实质上很多东西当我们回过头来看的时候会有不一样的收获,关于本篇的AOP功能和部分源码的理解基于尚硅谷雷丰阳老师Spring注解驱动开发的笔记总结,本文基于Spring版本为5.2.7版本,直接进入正题:

AOP功能测试

模拟一个计算的场景,在计算的过程中对业务方法进行增强,首先我们创建一个简单的Spring项目,至于创建的过程这里不在强调

  • 来看pom.xml
   
    
        org.springframework
        spring-context
        5.2.5.RELEASE
    

    
        junit
        junit
        4.12
        test
    

    
    
        org.springframework
        spring-webmvc
        5.2.5.RELEASE
    

    
    
        org.springframework
        spring-aspects
        5.2.5.RELEASE
    


这些依赖中其中最主要的是AOP模块,也就是我们的spring-aspects模块的引入

其次我们编写的我们的业务逻辑方法,代码如下:

/**
 * AOP逻辑类
 */
public class MathCalculator {

public int div(int i,int j){
    System.out.println("MathCalculator.....div....");
    return i /j;
}
}

代码简单,这里就不在啰嗦,接着定义一个日志切面类(LogAspect);其主要的目的是:切面类里面的方法需要动态感知MathCalculator.div运行到哪里然后执行,代码如下:

/**
 * AOP的切面类
 *
 * @Aspect 告诉spring当前类是一个却面类
*/
@Aspect
public class LogAspect {
//抽取公共的切入点表达式
@Pointcut("execution(public int com.cacmp.bean.aop.MathCalculator.*(..))")
public void pointCut(){
};

@Before("pointCut()")
public void  logStart(JoinPoint joinPoint){
    Object[] args = joinPoint.getArgs();
    System.out.println(joinPoint.getSignature().getName()+"除法运行...参数列表:{"+ Arrays.asList(args) +"}");
}

@After(value = "pointCut()")
public void  logEnd(){
    System.out.println("除法结束...");
}
@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+"}");
}

简单的来介绍下代码中用到的注解:

  • @Aspect:告诉spring当前类是一个切面类,在加入我们的IOC容器时,必须要贴注解,不然spring无法确认那个是我们定义的切面类
  • @Pointcut:表示切点,其中需要我们编写表达式来告诉spring我们切入具体的业务方法
  • 前置通知(@Before):logStart:在目标方法(div)运行之前运行
  • 后置通知(@After):logEnd:在目标方法(div)运行结束之后运行(无论方法正常结束还是异常结束)
  • 返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行
  • 异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行
  • 环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced())

接着我们将我们的业务逻辑类和切面类加入容器中,需要我们编写配置类:

@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAop {
//将逻辑类加入容器中
@Bean
public MathCalculator calculator(){
    return new MathCalculator();
}
//将切面类加入容器中
@Bean
public LogAspect aspect(){
    return new LogAspect();
}

其中注解@Configuration告诉spring这是一个配置类,@EnableAspectJAutoProxy此注解最为重要,其主要的目的是告诉Spring开启基于注解的AOP模式,后续的源码分析我们的入口就是此注解,当然在Spring中和Springboot中注解@Enablexxx很常见,同样我们也可以自定义自己的@Enablexxx注解编程,后续的文章后编写关于自定义注解驱动开发的入门教程,在整个Spring的历程中,最伟大的转折点就是Spring3.0之后出现的基于注解驱动开发,现在对于Spring的开发有两种模式:一种是基于接口编码的方式,一种基于@Enablexxx注解驱动的开发。闲话撤多了,我们来测试一下demo:

 //Aop测试
@Test
public void testAop(){
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAop.class);
    MathCalculator calculator = applicationContext.getBean(MathCalculator.class);
    calculator.div(10,5);

    applicationContext.close();
}

测试结果如下图所示:

AOP功能测试.png

那么关于注解版的AOP功能demo开发以及测试的编写就到这里,这并不是我们的重点,下节我们来分析其涉及到相关源码

你可能感兴趣的:(Spring注解驱动开发AOP功能)