Spring系列【AOP编程】

举报
周棋洛 发表于 2022/05/25 23:50:15 2022/05/25
【摘要】 ​ 如果觉得本文有帮助,请先赞后看,谢谢呀!🚀 文章目录 写在前面 🚀提出问题 🤪面向切面编程AOP 🎄AOP术语 🍭通知类型 🍹AOP 的类型 😮AOP 的优...

如果觉得本文有帮助,请先赞后看,谢谢呀!🚀

在这里插入图片描述


写在前面 🚀

前面学习了Spring的 IOC 及 DI 后,Spring还提供了对 AOP 的支持,AOP译为“面向切面编程”,和 OOP(面向对象编程)类似,它也是一种编程思想。AOP的本质也是解耦合,学习它🤪

提出问题 🤪

在实际开发中,处理业务开发,还有一些例日志管理,权限管理,事务控制,异常处理等的处理,这些功能虽然与应用的业务无关,但几乎所有的业务模块都会使用到他们,因此每个业务模块都要嵌入这些代码,这样就会产生大量重复的冗余代码,不利于各个模块的复用,你可能想过使用封装方法,在业务模块中调用的解决方案,确实可以,但是这种解决方案在一定的程度上减少了代码的冗余程度,但是这种做法也增加了业务模块和公用函数的耦合性,这种耦合性过高的解决方案是不推荐的。🥺

面向切面编程AOP 🎄

与 OOP 中纵向的父子继承关系不同,AOP 是通过横向的抽取机制实现的。它将应用中的一些非业务的通用功能抽取出来单独维护,并通过声明的方式(例如配置文件、注解等)定义这些功能要以何种方式作用在哪个应用中,而不是在业务模块的代码中直接调用。

OOP是纵向解决代码的冗余问题,它关注类和方法层的设计

AOP是横向解决代码的冗余问题,取代了传统继承体系重复代码的,例如性能分析,事务控制,等等……,实现业务逻辑和附加操作的代码解耦

目前最流行的 AOP 实现(框架)主要有两个,分别为 Spring AOP 和 AspectJ。
在这里插入图片描述

AOP术语 🍭

在这里插入图片描述

通知类型 🍹

在这里插入图片描述

AOP 的类型 😮

AOP 可以被分为以下 2 个不同的类型。动态AOP和静态AOP

动态 AOP 的织入过程是在运行时动态执行的。其中最具代表性的动态 AOP 实现就是 Spring AOP,它会为所有被通知的对象创建代理对象,并通过代理对象对被原对象进行增强。相较于静态 AOP 而言,动态 AOP 的性能通常较差,但随着技术的不断发展,它的性能也在不断的稳步提升。动态 AOP 的优点是它可以轻松地对应用程序的所有切面进行修改,而无须对主程序代码进行重新编译。

静态 AOP 是通过修改应用程序的实际 Java 字节码,根据需要修改和扩展程序代码来实现织入过程的。最具代表性的静态 AOP 实现是 AspectJ。相较于动态 AOP 来说,性能较好。但它也有一个明显的缺点,那就是对切面的任何修改都需要重新编译整个应用程序。

AOP 的优势 🐱‍🐉

AOP 是 Spring 的核心之一,在 Spring 中经常会使用 AOP 来简化编程。

在 Spring 框架中使用 AOP 主要有以下优势。

提供声明式企业服务,特别是作为 EJB 声明式服务的替代品,最重要的是,这种服务是声明式事务管理。
允许用户实现自定义切面。在某些不适合用 OOP 编程的场景中,采用 AOP 来补充。
可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时也提高了开发效率。

Spring AOP 是 Spring 框架的核心模块之一,它使用纯 Java 实现,因此不需要专门的编译过程和类加载器,可以在程序运行期通过代理方式向目标类织入增强代码。

第一个AOP程序开发

1.引入相关依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-expression</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.开发通知类

● MethodBeforeAdvice 前置通知
● MethodInterceptor 环绕通知
● AfterReturningAdvice 返回后通知
● ThrowsAdvice 异常通知

//自定义记录方法名称的前置通知 前置通知:目标方法执行之前先执行的额外操作
public class MyBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("当前执行的方法是:" + method.getName());
        System.out.println("当前执行的方法参数:" + args[0]);
        System.out.println("目标对象:" + target);
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3.Spring.xml中注册通知

<!--MyBeforeAdvice Bean-->
<bean id="myBeforeAdvice" class="vip.zhouql.advice.MyBeforeAdvice"/>

  
 
  • 1
  • 2

4.配置切面 通知 + 切入点

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--MyBeforeAdvice Bean-->
    <bean id="myBeforeAdvice" class="vip.zhouql.advice.MyBeforeAdvice"/>

    <!--组装切面-->
    <aop:config>
        <!--
        配置切入点
        id:    切入点在工厂中的唯一标识
        expression: 用来指定切入项目哪些组件中的哪些方法
        -->
        <aop:pointcut id="pc" expression="execution(* vip.zhouql.service.impl.UserServiceImpl.*(..))"/>

        <!--
        配置切面
        advice-ref:工厂中通知id
        pointcut-ref:工厂切入点唯一标识
        -->
        <aop:advisor advice-ref="myBeforeAdvice" pointcut-ref="pc"/>
    </aop:config>
</beans>

  
 
  • 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

5.测试

public class TestSpring {
    public static void main(String[] args) {
        String springName = "spring.xml";
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(springName);
        UserService userService = (UserService) context.getBean("userService");
        userService.save();
        userService.delete();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

6.结果

可以看到在方法执行前,通过spring aop 实现了前置通知,OK,Perfect 🚀

当前执行的方法是:save
目标对象:vip.zhouql.service.impl.UserServiceImpl@180cb77
调用DAO,完成添加
当前执行的方法是:delete
目标对象:vip.zhouql.service.impl.UserServiceImpl@180cb77
调用DAO,完成删除

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这就是全部的内容了,拜拜了你 🐱‍🐉

文章来源: blog.csdn.net,作者:周棋洛ყ ᥱ ᥉,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/m0_53321320/article/details/123699123

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。