AOP学习笔记

概念

什么是AOP

(1) 面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

(2) 通俗描述:不通过修改源代码方式,在主干功能里面添加新功能

(3) 使用登录例子说明AOP

登录例子

术语

连接点(join point):类里面那些可以被增强的方法叫连接点。

切入点(point cut):实际被真正增强的方法叫切入点。

通知(advice):

  1. 实际增强的逻辑部分称为通知(增强)
  2. 通知有多种类型
    1. 前置通知
    2. 后置通知
    3. 环绕通知
    4. 异常通知
    5. 最终通知 finally

切面(aspect):是动作,把通知应用到切入点的过程叫切面。

 

图示:

 

AOP与OOP的关系

OOP-面向对象程序设计的特点:

  1. 封装性:将数据与对数据的操作封装到一个实体(类)中,实现高内聚、低耦合。
  2. 继承性:两个或两个以上类之间的关系,一个类可以从其父类中继承一些特性,比如成员属性和方法。可以简化重复代码,方便管理相似特性
  3. 多态性:从一个类创建的一组对象中,调用同名函数,不同的对象中做的事情不同。

 

AOP-面向切面编程的特点:

  1. 通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。
  2. AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容。
  3. 利用AOP可以对业务逻辑的各个部分进行隔离,从而降低业务逻辑各部分之间的耦合度,提高程序的可重用性,提高开发效率。
  4. 将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来

 

OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。

而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

这两种设计思想在目标上有着本质的差异,OOD/OOP面向名词领域,AOP面向动词领域。

我的理解:

我们系统中一定包含业务逻辑和与业务关系不大的日志、事务、性能等部分。

对于OOP,类中需要把业务逻辑和非业务的其他逻辑都囊括进去,它解决的是类内部结构和类与类之间的关系。

而AOP,将类中业务的和非业务的逻辑分割开来,非业务的部分给AOP去管理,暴露出业务的实现切面(入口),只需要专注做好业务的部分即可。

 

AOP底层原理

AOP底层使用动态代理,有两种代理方式

(1)有接口情况,使用JDK动态代理

创建接口实现类代理对象,增强类的方法

(2)没有接口情况,使用CGLIB动态代理

AOP操作(准备)

  1. Spring框架一般都是基于AspectJ实现AOP操作

(1)什么是AspectJ?

AspectJ不是Spring组成部分,独立于AOP框架。一般把AspectJ和Spring框架一起使用,进行AOP操作

 

 

  1. 基于AspectJ实现AOP操作

(1)基于xml配置文件实现

(2)基于注解方式实现(使用)

 

  1. 在项目工程里引入AOP相关的依赖
  2. 切入点表达式

(1)切入点表达式作用:指定对哪个类里面的哪个方法进行增强

(2)语法结构:execution([权限修饰符][返回类型][完全限定符][方法名称][参数列表])

 

举例:

execution(* com.chen.UserDAO.add(..)) // 对add方法增强

execution(* com.chen.UserDAO.*(..)) // 对UserDAO文件中所有方法增强

execution(* com.chen.*.*(..)) // 对com.chen下所有包的所有方法增强

 

AOP操作—注解方式

  1. 创建被增强类User
  2. 创建增强代理类UserProxy
  3. 进行通知配置
  • 创建Spring配置文件,在其中开启注解扫描
  • 使用注解创建User和UserProxy对象:在类上加 @Component
  • 在增强类UserProxy上添加@Aspect注解
  • 在Spring配置文件中开启生成代理对象:增加aspectj-autoproxy节点
<!-- 配置扫描包路径 -->
<context:ComponentScan basePackage="com.chen"></context>
<!-- 配置aspectj自动代理 -->
<aop:aspectj-autoproxy></aop>
  1. 配置不同类型的通知 @Before,@After

注解类

@Component
public class User {
	public void add() {
        System.out.println("add..........");
    }
}
@Component
@Aspect
public class UserProxy {
    // 前置通知
    @Before(value="execution(* com.chen.User.add(..))")
	public void addBefore() {
        System.out.println("before..........");
    }

    // 最终通知
    @After(value="execution(* com.chen.User.add(..))")
	public void after() {
        System.out.println("After..........");
    }

    // 异常通知
    @AfterThrowing(value="execution(* com.chen.User.add(..))")
	public void afterThrowing() {
        System.out.println("AfterThrowing..........");
    }

    // 后置通知
    @AfterReturning(value="execution(* com.chen.User.add(..))")
	public void afterReturning() {
        System.out.println("AfterReturning..........");
    }

    // 环绕通知
    @Around(value="execution(* com.chen.User.add(..))")
	public void around(ProceedingJoinPoint proceedingJoinPoint) {
        System.out.println("Around before..........");

        // 被增强方法
        proceedingJoinPoint.proceed();

        System.out.println("Around After..........");
    }
}
  1. 抽取公共的切入点
@Component
@Aspect
public class UserProxy {
    @Pointcut("execution(* com.chen.User.add(..))")
    public void pointDemo() {
        
    }
    
    // 前置通知
    @Before(value="pointDemo()")
	public void before() {
        System.out.println("before..........");
    }
}
  1. 多个增强类对同一个方法增强,在增强类上设置优先级

在增强类上加一个注解:@Order(数字类型的值) 数字越小,优先级越高

@Component
@Aspect
@Order(1)
public class UserProxy1 {
     @Before(value="execution(* com.chen.User.add(..))")
	public void before() {
        System.out.println("before1..........");
    }
}

@Component
@Aspect
@Order(2)
public class UserProxy2 {
     @Before(value="execution(* com.chen.User.add(..))")
	public void before() {
        System.out.println("before2..........");
    }
}

AOP操作—XML配置方式

  1. 创建两个类,增强类和被增强类,创建方法
  2. 在Spring配置文件中创建两个类对象
  1. 在Spring配置文件中配置切入点
<!-- 创建对象 -->
<bean id="user" class="com.chen.User"></bean>
<bean id="userProxy" class="com.chen.UserProxy"></bean>

<!-- 配置aop增强 -->
<aop:config>
	<!--  配置切入点  -->
	<aop:pointcut id="point" expression="execution(* com.chen.User.add(..))">
	<!--  配置切面(把增强类的增强方法应用到切入点上)  -->
  <aop:aspect ref="UserProxy">
		<!--   增强方法是addBefore,应用到的切入点id为point   -->
    <aop:before method="addBefore" pointcut-ref="point">
  </aop:aspect>
</aop:config>

AOP操作—完全注解方式

增强类和被增强类跟注解方式一致。

增加一个配置类

@Configuration
@ComponentScan(basePackages={"com.chen"})
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class config {

}

 声明:本文参考b 站 尚硅谷React视频。

posted @   怡然525  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示