Spring AOP

AOP编程

  1. 静态代理
    • 在真实主题之间,前后均可包一层,实现代理的额外拓展功能+真实主题的原来实现,目的是在不破坏原来真实主题的目标意图和功能下,对真实主题进行了功能加强和扩展。
    • 缺点:
    • 尽管能实现:在不改变原来代码的情况下,新增加了需要的功能。
    • 随之带来了新的问题:一个类对应一个接口,代理类也对应实现类同样的接口,虽然我们把散落在系统中各个方法都收集回笼到一块,但一个接口就要出来一个代理类导致数量膨胀,不利于管理
  2. JDK动态代理
    • 是基于接口实现的,也就是只能对该类所实现接口中定义的方法进行代理,整个系统中一份。
    • 通过反射类Proxy以及InvocationHandler回调接口实现的。
  3. CGLIB代理
    • 是一个功能强大,高性能的代码生成包,为没有实现接口的类提供代理。
    • 原理:动态生成一个被代理类的子类,子类重写被代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势植入横切逻辑。
    • 新增jar包,cglib-nodep-2.1_3.jar

AOP相关概念

  1. 横切性关注点
    • 加在主业务前后的内容称为“横切性关注点”。根据OOP编程原则,提供给多个地方调用的内容需要将它封装为一个方法,方法也不可能单独存在,需要存在一个类中,由此引入了后续概念。
  2. 通知(advice)
    • 将横向业务内容也即横切性关注点的内容封装为一个方法,这个方法称为“通知”,它可以放在主方法的前面,也可以放在后面。除此以外还有异常通知、环绕通知和最终通知。即被方法化的横切性关注点称为通知。
  3. 连接点(joinpoint)
    • 就是那些被拦截到的点,spring这些点就是方法。也就是主业务中的主要方法,每一个方法就是一个连接点,比如User类的CRUD就是4个连接点。
  4. 切入点(pointcut)
    • 就是要对那些方法进行拦截,是对需要拦截的joinpoint的定义。
  5. 切面(aspect)
    • 一个个封装了的方法称为advice,每一个方法均应该封装在一个类中,此外,在这些advice上也需要定义将这些通知用于那些方法前面后面,这些定义也封装在这个类中,称为切入点,它们以后作用于joinpoint将这些统一封装起来的类称为切面。公式表达:aspect=pointcut+advice
  6. 织入(weave)
    • 将aspect运用到代理的目标对象上并导致proxy创建的过程称为织入。
###Spring AOP 的概念 AOP(Aspect-Oriented Programming)即面向切面编程,是一种编程范式,旨在通过分离横切关注点来提高模块化程度。在 Spring 框架中,AOP 被广泛用于实现诸如日志记录、事务管理、安全性等通用功能,这些功能通常与业务逻辑无关但又需要在多个地方重复使用。 Spring AOP 主要是基于 AspectJ 实现的,尽管 AspectJ 是一个独立的 AOP 框架,并不是 Spring 的组成部分,但它通常与 Spring 一起使用以提供更强大的 AOP 功能[^1]。Spring AOP 支持两种方式来定义切面:基于 XML 配置文件的方式和基于注解的方式。 ###Spring AOP 的原理 Spring AOP 使用运行时代理来实现 AOP 功能,这意味着它会在运行时动态生成代理对象。对于实现了接口的类,Spring AOP 默认使用 JDK 动态代理;而对于没有实现接口的类,则会使用 CGLIB 代理[^4]。这种方式允许在不修改原始代码的情况下向程序中添加新的行为。 织入(Weaving)是将增强(advice)应用到目标对象的过程,Spring AOP 在运行时进行织入操作[^3]。当创建了代理对象后,所有对目标对象方法的调用都会被拦截,并且可以插入额外的操作,比如在方法执行前后做一些处理。 ###Spring AOP 的使用教程 要开始使用 Spring AOP,首先需要确保项目中包含了必要的依赖。如果使用 Maven 构建工具,可以在 `pom.xml` 文件中加入如下依赖: ```xml <!-- 引入aop依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` 一旦添加了依赖并刷新了 Maven 项目,就可以开始编写切面了。下面是一个简单的例子,展示如何使用注解来定义一个切面: ```java import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("Method " + joinPoint.getSignature().getName() + " is called."); } } ``` 在这个示例中,`LoggingAspect` 类被标记为 `@Aspect` 和 `@Component` 注解,这样 Spring 就能识别这是一个切面组件。`@Before` 注解指定了在哪些方法上应用前置通知(before advice),这里的表达式表示匹配 `com.example.service` 包下所有的方法。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值