• SpringAOP是什么?为什么要有SpringAOP?


    SpringAOP是什么?为什么要有SpringAOP?

    原文:SpringAOP是什么?为什么要有SpringAOP?

    一、有SpringAOP之前

    简单的开发场景,只需要写简单的业务逻辑,比如CRUD

    但是在执行具体的逻辑之前,需要进行权限校验,或者在具体的逻辑之后,需要日志记录呢?

    这样就增加了很多代码,而且增加的这些代码都是差不多的

    既然如此,那我们抽出来吧!在这个类里面写一个私有的方法。

    代码少了很多,但是如果其他的类也需要用到权限校验和日志记录呢?

    难道也要在其他类里面写私有方法吗?这也太麻烦了。

    为了解决这个问题,有两种方法。

    第一种:将这个私有方法抽出来不就好了,我直接写两个工具类,一个是权限校验,一个是日志记录,谁用谁调用。

    第二种:我直接搞一个父类,谁用我就让它继承这个父类,这样就能直接调用父类的方法。

    但是不论是第一种还是第二种其实都会侵入业务类的方法逻辑,那么有没有一种方法,能在没有对业务核心代码侵入性的前提下,给业务核心代码添加额外的功能呢?

    这时候AOP就出来了,也就是所谓的面向切面编程。

    首先来看一下AOP的概念:

    切入点:

    想额外添加功能的方法

    切面:

    权限检查、日志记录等这些增强逻辑的方法在的类

    通知:

    在目标方法运行的什么时机来执行某个增强逻辑

    目标方法前还是目标方法后

    切入点表达式:

    规定增强逻辑需要去增强什么方法

    二、有SpringAOP之后

    使用方法:

    maven依赖

    <dependencies>
            
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-contextartifactId>
                <version>5.3.23version>
            dependency>
    
            
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-aspectsartifactId>
                <version>5.3.1version>
            dependency>
    
            
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>1.18.30version>
            dependency>
    
            
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>4.13.2version>
                <scope>testscope>
            dependency>
        dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    切入点

    package com.moon.aop.bean;
    
    /**
     * @Author moon
     * @Date 2023/10/15 15:55
     * @Description 切入点
     */
    public class UserService {
    
        public void addUser() {
            System.out.println("添加用户...");
        }
    
        public void queryUser() {
            System.out.println("查询用户...");
        }
    
        public void editUser() {
            System.out.println("编辑用户...");
        }
    
        public void deleteUser() {
            System.out.println("删除用户...");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    切面

    package com.moon.aop.bean;
    
    /*
    * 底层依赖Aspect的注解【但是原理不同】
    * */
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    
    /**
     * @Author moon
     * @Date 2023/10/15 15:58
     * @Description 切面,里面放的增强逻辑
     */
    
    @Aspect
    public class UserAspect {
    
        /*
        * 这就是传说中上文所谓的切入点表达式
        * */
        @Pointcut(value = "execution(* com.moon.aop.bean.UserService.*(..))")
        public void point() {
        }
    
        /*
        * 这就是增强逻辑
        * @Before、@After就是所谓的通知
        * */
        @Before(value = "point()")
        public void beforeRun() {
            System.out.println("在目标方法执行前开始执行");
        }
    
        @After(value = "point()")
        public void afterRun() {
            System.out.println("在目标方法执行后开始执行");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    配置类:用来初始化和加载Spring的IOC容器

    package com.moon.aop.bean;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    /**
     * @Author moon
     * @Date 2023/10/15 16:07
     * @Description 用该类来初始化和加载IOC容器
     */
    
    @Configuration
    public class SpringConfig {
    
        @Bean
        public UserAspect userAspect() {
            return new UserAspect();
        }
    
        @Bean
        public UserService userService() {
            return new UserService();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    Junit单元测试

    import com.moon.aop.bean.SpringConfig;
    import com.moon.aop.bean.UserService;
    import org.junit.Test;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * @Author moon
     * @Date 2023/10/15 16:32
     * @Description
     */
    public class AOPTest {
    
        @Test
        public void test01() {
            /*
            * 通过配置类初始化IOC容器
            * */
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
            /*
            * 获取目标对象,Bean
            * */
            UserService userService = context.getBean(UserService.class);
            userService.addUser();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述

    AOP并没有生效

    此时userService.getClass().getName()的值为

    在这里插入图片描述

    那是因为Spring并没有开启AOP,需要我们手动开启

    package com.moon.aop.bean;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    /**
     * @Author moon
     * @Date 2023/10/15 16:07
     * @Description 用该类来初始化和加载IOC容器
     */
    
    @Configuration
    /*
    * 手动开启AOP功能
    * */
    @EnableAspectJAutoProxy
    public class SpringConfig {
    
        @Bean
        public UserAspect userAspect() {
            return new UserAspect();
        }
    
        @Bean
        public UserService userService() {
            return new UserService();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这里插入图片描述

    成功!

    此时userService.getClass().getName()的值为

    在这里插入图片描述

  • 相关阅读:
    快速掌握JVM及垃圾回收器
    【云原生之kubernetes实战】在k8s环境下安装Taskover任务管理工具
    运维-技能大杂烩
    React中实现大模型的打字机效果
    2216.美化数组的最少删除数
    ConcurrentHashMap底层原理(1.7&1.8)
    ros建图过程中给上位机发布地图信息
    python每日一题【剑指 Offer 10- I. 斐波那契数列】
    基于springboot的鲜花销售商城网站
    docker安装php7.4安装(swoole)
  • 原文地址:https://blog.csdn.net/qq_41298636/article/details/133844680