1.aop概念
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的一个重要组成部分,它提供了在运行时将横切关注点(cross-cutting concerns)代码插入到应用程序中的机制。AOP使得开发者能够将业务逻辑与那些跨越多个对象的通用功能(如日志记录、事务管理、权限控制等)分离。
切面(Aspect):一个关注点的模块化,通常实现为一个类。
连接点(Joinpoint):程序执行过程中的某个特定点,比如方法调用或异常抛出。
通知(Advice):在特定的连接点上执行的动作,可以是“前置”、“后置”、“环绕”等类型。
切入点(Pointcut):匹配连接点的表达式,用来指定哪些连接点会触发通知。
目标对象(Target Object):被一个或多个切面所通知的对象。
代理(Proxy):Spring AOP使用代理模式来实现切面,被代理的对象称为目标对象,而代理对象则包含了额外的业务逻辑。
织入(Weaving):将切面连接到其他应用程序类型或对象的过程,可以在编译时或运行时完成。
2.优缺点
优点
模块化:通过将关注点分离,可以使代码更加清晰和可维护。
减少代码重复:通用的功能可以通过AOP来实现,避免在多个地方重复编写相同的代码。
易于扩展:新的横切关注点可以通过定义新的切面轻松添加,而不必修改现有的代码。
解耦:业务逻辑和横切关注点之间没有直接的依赖关系,这有助于提高系统的灵活性和可测试性。
缺点
性能开销:由于增加了额外的代理和动态生成类的操作,可能会对系统性能产生一定的影响。
调试复杂性:由于代码的执行流被切面改变了,可能会使调试变得更加困难。
学习曲线:理解和使用AOP需要一定的学习成本,特别是对于新手来说。
配置复杂度:虽然Spring提供了多种方式来配置AOP,但有时这些配置可能变得相当复杂。
3.代码示例[实现前置、后置通知]
3.1.pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hairuo</groupId>
<artifactId>spring-aop</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--spring核心依赖,会将spring-aop传递进来-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<!--切入点表达式依赖,目的是找到切入点方法,也就是找到要增强的方法-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
</project>
3.2.spring配置类
package com.hairuo.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan("com.hairuo")
@EnableAspectJAutoProxy
public class SpringConfig {
}
3.3.dao
public interface BookDao {
public void update();
}
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println(System.currentTimeMillis());
System.out.println("book dao save ...");
}
public void update(){
System.out.println("book dao update ...");
}
}
3.4.aspect
@Component
@Aspect
public class Myadvice {
@Pointcut("execution(void com.hairuo.dao.impl.BookDaoImpl.update())")
private void pt(){}
@Before("pt()")
public void method(){
System.out.println(System.currentTimeMillis());
}
@After("pt()")
public void method2(){
System.out.println(System.currentTimeMillis());
}
}
3.5.测试主函数
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = ctx.getBean(BookDao.class);
bookDao.update();
}
}
4.总结
博主认为java spring的aop切面编程,类似于python的装饰器,方便将日志记录、测试等通用功能提取,在不改变原来代码的基础上增强功能。部分单一需求场景适用,对于复杂的业务场景并不能总是适用,一味的追求aop反而会带来很多副作用。因此,aop可以作为一种设计模式去参考,而不能作为一种必选范式应用到日常的架构设计、程序开发中,否则会适得其反。
5.源码工程
https://download.csdn.net/download/qq_34321590/89619637?spm=1001.2014.3001.5503