[TOC]
# 1. 在Springboot中,可以按以下步骤面向切面设计程序:
## 1.1. 定义切面
(Aspect)类并添加`@Aspect`注解,标识该类是一个切面类。
```
@Aspect
public class MyAspect {
}
```
## 1.2. 在切面类中定义切入点
(Pointcut)方法,使用@Pointcut注解标识,指明该方法是一个切入点方法。
```
@Aspect
public class MyAspect {
@Pointcut("execution(* com.example.demo.controller.*.*(..))")
public void pointcut() {}
}
```
## 1.3. 在切面类中定义通知
(Advice)方法,并通过注解指定切入点方法,标识该通知方法将要织入的切入点。支持前置通知(@Before)、后置通知(@After)、返回通知(@AfterReturning)、异常通知(@AfterThrowing)和环绕通知(@Around)。
```
// 定义切面
@Aspect
public class MyAspect {
// 定义切入点
@Pointcut("execution(* com.example.demo.controller.*.*(..))")
public void pointcut() {}
// 定义通知
@Before("pointcut()")
public void before() {
System.out.println("Before advice");
}
}
```
## 1.4. 将切面类加入到Spring Ioc容器中。
可以使用@Component注解、配置类中@Bean方法或者<aop:aspectj-autoproxy />自动代理形式加入。
```
@Component
@Aspect
public class MyAspect {
}
```
## 1.5. JDK动态代理或CGLIB为目标对象生成代理对象
Spring会通过JDK动态代理或CGLIB为目标对象生成代理对象,并在代理对象中织入切面,实现对目标方法的增强。
## 1.6. 指定切面执行的顺序(如果有多个切面)。
可以使用@Order注解或者在配置类中通过@Bean的order属性指定顺序。
```
@Aspect
@Order(1)
public class MyAspect1 {
}
@Aspect
@Order(2)
public class MyAspect2 {
}
```
以上就是在Springboot中面向切面设计程序的步骤和方式。通过切面、通知和切入点,可以实现`日志记录、权限校验、事务处理等横切功能,降低程序耦合,提高程序扩展性和维护性。`
## 1.7. 其他要点:
除上面提到的面向切面设计的基本步骤外,在Springboot中还有一些其他要点:
*****
1). **基于注解的切面(@Aspect)与基于XML的切面`(<aop:aspectj-autoproxy />)`可以混合使用**,Spring会自动将它们组合在一起。
2). 可以使用`AspectJ`切入点表达式语言,它比`Spring AOP`的表达式语言**更强大**,支持更复杂的切入点匹配。
3). 切入点表达式可以**匹配**方法入参,返回值类型,方法抛出的异常等。
4). 可以在通知方法中**获取织入点**方法的入参,返回值等信息。通过`JoinPoint`参数。
5). 可以在通知方法中**阻止织入点**方法的执行。仅在环绕通知中通过控制`proceed()`方法的调用来实现。
6). Spring AOP默认只会代理public方法。如果需要代理非public方法,需要设置`proxy-target-class="true"`。
7). 可以在`spring.aop.*`下设置一些AOP相关的属性,如是否使用CGLIB代理等。
8). 可以**自定义切面**,通过实现`MethodInterceptor`接口并注册到`Spring Ioc`容器来实现。
9). 目前主流的AOP框架有`AspectJ、Spring AOP`等。AspectJ性能更好,但是Spring AOP更简单易用,两者可以很好结合。
```
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // 使用CGLIB代理
public class AopConfig {
}
@Aspect
public class MyAspect {
@Pointcut(...)
public void pointcut() {}
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
// Before advice
Object result = pjp.proceed(); // 调用织入点方法
// After advice
return result;
}
}
```
综上,Springboot提供了基于注解和`XML`的方式来方便地面向切面设计程序,通过切面、通知、切入点的组合,使横切关注点如日志、事务、权限等与业务逻辑解耦,实现高内聚低耦合的单元,增强程序扩展性和维护性。
# 2. Spring AOP组成部分
## 2.1. 切面(Aspect):
通知和切入点的结合。
## 2.2. 切入点(Pointcut):
用于定义需要应用通知的连接点集合。Spring支持模糊匹配包、类型和方法。
## 2.3. 通知(Advice):
通知方式:Before、After、After-returning、After-throwing、Around。
## 2.4. 织入(Weaving):
将切面应用到目标对象并创建代理的过程。Spring AOP使用JDK动态代理和CGLIB来进行织入。
## 2.5. 目标对象(Target Object):
需要应用通知的对象。
|Spring AOP的主要组成部分|说明|业务代码实现流程|技术边界|
|:--:|:--:|:--:|:--:|
|切面(Aspect)|通知和切入点的结合。|-|@Aspect<br>public class MyAspect{...}|将切面标注为@Aspect
|切入点(Pointcut)|用于定义需要应用通知的连接点集合。Spring支持模糊匹配包、类型和方法。|<aspectj>pointcut expression</aspectj>|表达式的编写难度较大,定制性不强|
|通知(Advice)|
|前置通知(Before)|在切入点方法执行前执行。|@Before("pointcut expression")<br>public void before(){...}|与切入点表达式绑定
|后置通知(After)|在切入点方法执行后执行。|@After("pointcut expression")<br>public void after(){...}|与切入点表达式绑定
|返回通知(After-returning)|在切入点方法成功执行后执行。|@AfterReturning("pointcut expression")<br>public void afterReturning(){...}|与切入点表达式绑定
|异常通知(After-throwing)|在切入点方法抛出异常后执行。|@AfterThrowing("pointcut expression")<br>public void afterThrowing(){...}|与切入点表达式绑定
|环绕通知(Around)|在切入点方法执行前后执行,并决定是否执行切入点方法。|@Around("pointcut expression")<br>public void around(ProceedingJoinPoint pjp){...}|需要手动调用ProceedingJoinPoint的proceed()方法执行切入点方法
|织入(Weaving)|将切面应用到目标对象并创建代理的过程。Spring AOP使用JDK动态代理和CGLIB来进行织入。|-|Spring AOP 在运行时通过JDK动态代理或CGLIB为目标对象创建代理来织入切面|需要目标对象实现接口或为非final类
|目标对象(Target Object)|需要应用通知的对象。|-|无特殊要求|无特殊要求
# 3. AspectJ 组成部分
|组成部分|说明|
|:--|:--|
|Aspect|切面,用来定义切点和通知|
|Pointcut|切点,匹配连接点的表达式|
|Advice|通知,在切点匹配的连接点执行的动作|
|Joint point|连接点,程序执行的某个点|
|Weaving|织入,将Aspect应用到目标对象并创建代理的过程|
## 3.1 使用场景
|场景|示例|
|:--|:--|
|**日志记录**|**在方法执行前后打印日志**|
|性能监控|记录方法执行时间|
|事务管理|根据方法注解开启事务|
|异常处理|捕获方法抛出的异常|
|权限控制|检查用户权限后执行方法|
## 3.2 代码示例
```
public aspect LoggingAspect {
pointcut methodExecution() : execution(* *(..));
before() : methodExecution() {
System.out.println("方法执行前...");
}
after() : methodExecution() {
System.out.println("方法执行后...");
}
}
```
**在上例中定义了一个LoggingAspect,在所有方法执行前后打印日志。**
## 3.3 技术边界
|特征|支持|说明|
|:--|:--|:--|
|AOP面向切面|是|AspectJ是AOP的代表框架|
|静态织入|是|在编译时将Aspect织入目标类|
|动态织入|是|在运行时将Aspect织入目标类|
|基于代理|是|使用JDK动态代理或CGLIB创建目标类代理|
|基于字节码|是|使用ASM或AspectWerkz工具修改目标类字节码|
|多语言|否|AspectJ是Java语言的AOP框架|
> AspectJ是一款功能强大、具有代表性的AOP框架,它不仅展示了AOP编程模型的威力,也推动了AOP思想在企业应用中的采用和发展。但是,AspectJ仅限于Java平台,若要实现跨语言的AOP尚需其他解决方案。
- 系统设计
- 需求分析
- 概要设计
- 详细设计
- 逻辑模型设计
- 物理模型设计
- 产品设计
- 数据驱动产品设计
- 首页
- 逻辑理解
- 微服务架构的关系数据库优化
- Java基础架构
- 编程范式
- 面向对象编程【模拟现实】
- 泛型编程【参数化】
- 函数式编程
- 响应式编程【异步流】
- 并发编程【多线程】
- 面向切面编程【代码复用解耦】
- 声明式编程【注解和配置】
- 函数响应式编程
- 语法基础
- 包、接口、类、对象和切面案例代码
- Springboot按以下步骤面向切面设计程序
- 关键词
- 内部类、匿名类
- 数组、字符串、I/O
- 常用API
- 并发包
- XML
- Maven 包管理
- Pom.xml
- 技术框架
- SpringBoot
- 项目文件目录
- Vue
- Vue项目文件目录
- 远程组件
- 敏捷开发前端应用
- Pinia Store
- Vite
- Composition API
- uniapp
- 本地方法JNI
- 脚本机制
- 编译器API
- 注释
- 源码级注释
- Javadoc
- 安全
- Swing和图形化编程
- 国际化
- 精实或精益
- 精实软件数据库设计
- 精实的原理与方法
- 项目
- 零售软件
- 扩展
- 1001_docker 示例
- 1002_Docker 常用命令
- 1003_微服务
- 1004_微服务数据模型范式
- 1005_数据模型
- 1006_springCloud
- AI 流程图生成
- Wordpress_6
- Woocommerce_7
- WooCommerce常用的API和帮助函数
- WooCommerce的钩子和过滤器
- REST API
- 数据库API
- 模板系统
- 数据模型
- 1.Woo主题开发流程
- Filter
- Hook
- 可视编辑区域的函数工具
- 渲染字段函数
- 类库和框架
- TDD 通过测试来驱动开发
- 编程范式对WordPress开发
- WordPress和WooCommerce的核心代码类库组成
- 数据库修改
- 1.WP主题开发流程与时间规划
- moho
- Note 1
- 基础命令