Spring注解驱动开发AOP功能

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

AOP功能测试

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

  • 来看pom.xml
   <dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>

</dependencies>

这些依赖中其中最主要的是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开发以及测试的编写就到这里,这并不是我们的重点,下节我们来分析其涉及到相关源码

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351