AOP的理解以及示例

关于Spring AOP的理解

AOP为Aspect Oriented Programming的缩写 :面向切面编程, AOP是OOP的延续 AOP并不是一种技术,只是一种思想,即面向切面编程的思想

在开发中日志的使用时很频繁的,下面就来用AOP来解决一下开发中的日志输出的问题

@Service
public class TestService {

    public int sum(int a ,int b ){
        System.out.println("参数为:"+a+"+"+b);
        int sum = a+b;
        System.out.println("结果为:"+sum);
        return sum;
    }
}
@Autowired
private TestService testService;

@Test
void contextLoads() {
    testService.sum(1,2);
}
参数为:1+2
结果为:3

在不使用aop的情况下,我们打印日志要这样写,这样写的话就是业务代码跟日志输出都写在了一起,使得代码冗余,而且在后面假如说,不需要将参数输出到日志中了,这样需要一个类一个类的修改代码,工作量时很大的

AOP就很方便简单的解决了这个问题

AOP的理解

image-20200815173638193.png

这是之前的日志输出方法

image-20200815173809830.png

这个时使用AOP的日志输出方法

其实AOP,面向切面很好理解,就是在一个类上横切一刀,将我们需要的代码切入,并且不影响之前代码的执行,实现了解耦

image-20200815181439994.png

AOP的优点

1、面向切面编程使得每个关注点都集中于一个地方而不是分散在多处代码中,便于后期的统一维护管理。

2、服务模块更简洁,它们只包含主要关注点,而次要关注点的代码被转移到切面中了。

3、对原方法进行方法增强,且不影响原方法的正常使用。

4、使用简单可插拔的配置,在实际逻辑执行之前、之后或周围动态添加横切关注点。

AOP的术语

名称 描述
切面(Aspect) 切面是通知和切点的结合
通知(Advice) 通知定义了切面是什么以及何时使用。除了描述切面要完成的工作,通知还解决了何时执行这个工作的问题
切点(Pointcut) 切点定义了在何处工作,也就是真正被切入的地方,也就是在哪个方法应用通知
连接点(Join point) 连接点是在应用执行过程中能够插入切面的一个点
引入(Introduction) 引入让一个切面可以声明被通知的对象实现了任何他们没有真正实现的额外接口,而且为这些对象提供接口的实现
织入(Weaving) 织入是把切面应用到目标对象并创建新的代理对象的过程

其中在Spring中有5中通知类型

名称 描述
前置通知(Before) 在目标方法被调用之前调用
后置通知(After) 在目标方法完成之后调用
返回通知(After-returning) 在目标方法成功执行之后调用
异常通知(After-throwing) 在目标方法抛出异常后调用
环绕通知(Around) 通知包裹了被通知的方法,可同时定义前置通知和后置通知

SpringBoot 实现AOP

  1. 新建一个SpringBoot项目

  2. 导入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
    </dependency>
    
  3. AOP的实现需要进行配置,在Spring 中使用的时xm的方式进行配置,但是在SpringBoot中取消了xml,改为使用了配置类进行配置

    package com.mango.Aspect;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    /**
     * @Author:  
     * @Date:     
     * @Component 被Spring管理
     * @Aspect 声明他是一个aop的类
     */
    @Component
    @Aspect
    public class TestAspect {
    
        /**
         *  @Pointcut("execution(* com.mango.service.*.*(..))")
         *  execution 括号中的是一个表达式,表面在com.mango.service 这个包下的所有类所有方法所有返回值,所有参数
         *  申明切入点
         *  execution 关键字
         *  *           com.mango.service. *.    *          (..)  )
         *  所有的返回值  包名                         所有类 所有方法   所有的参数
         */
        @Pointcut("execution(* com.mango.service.*.*(..))")
        public void pointcut(){}
    
        /**
         * @Before("pointcut()")  前置通知,在切入点之前
         * @param joinPoint  可以通过他来获取方法以及参数
         */
        @Before("pointcut()")
        public void before(JoinPoint joinPoint){
            Object [] args = joinPoint.getArgs();
            for (Object arg : args) {
                System.out.println("参数为:"+arg);
    
            }
        }
    
        /**
         * @param joinPoint
         * @param returnValue
         * @AfterReturning(value = "pointcut()",returning = "returnValue")
         * returning 获取返回值
         */
        @AfterReturning(value = "pointcut()",returning = "returnValue")
        public void returning(JoinPoint joinPoint,Object returnValue){
            System.out.println("结果为:"+returnValue);
        }
    }
    
@Service
public class TestService {

    public int sum(int a ,int b ){

        int sum = a+b;

        return sum;
    }
}
@SpringBootTest
class SpringbootAopApplicationTests {
    @Autowired
    private TestService testService;

    @Test
    void contextLoads() {
        testService.sum(1,2);
    }

}
参数为:1
参数为:2
结果为:3

其他的After之类的就不再举例了,用法都是一样的

这样就是实现了AOP,是不是很简单,其实AOP的使用时很简单的,重要的是理解AOP的这种思想

AOP的运用的技术

SpringAOP使用了两种代理机制,一种是基于JDK的动态代理,另一种是基于CGLib的动态代理,之所以需要两种代理机制,很大程度上是因为JDK本身只提供基于接口的代理,不支持类的代理。

切面植入的方法:

编译期织

类装载期织入

动态代理织入 在运行期为目标类添加增强生成子类的方式,Spring AOP采用动态代理织入切面

AOP 有两种主要的框架,SpringAOP和AspectJ

在一般情况下使用SpringAOP就可以解决我们的问题,如果无法解决,Spring支持对AspectJ 的集成,可以使用AspectJ解决

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