SpringBoot 02 AOP

发布于:2025-08-03 ⋅ 阅读:(8) ⋅ 点赞:(0)

如果要重用通用功能,可以采用继承或者组合,它们对业务类有侵入性。切面是一种更清晰简洁的方法,它完全实现开闭原则,业务类不知道切面类的存在,完全聚焦业务功能。

AOP

AOP(Aspect-Oriented Programming,面向切面编程)是Springboot 的核心概念。它是面向对象编程的一种延续。
它将公共模块(日志,事务,权限,监控)代码与业务模块代码分开开发,通过动态代理实现两者组合发挥功能。

术语

连接点:应用程序执行过程中能够插入切面的点。点可以是调用方法, 抛出异常时。
切点:通过正则表达式匹配的连接点的集合。在这些连接点均执行通知。
通知:定义切面要完成的工作内容以及工作时机。时机是相对于目标方法而言的。按照时机可以分为前置通知,后置通知,环绕通知,正常返回通知,异常返回通知。环绕通知等于前置通知+后置通知。
目标对象:被代理对象。
引入:不修改目标类,向目标类添加新方法或者属性。
切面:等于切点+通知。
织入:将切面应用到目标对象,创建新的代理对象。按照目标对象的生命周期可以分为:编译期织入,AspectJ就是这种。类加载期织入。运行期织入。
通过动态代理,生成代理对象。就是将通知应用到切点。

切点指示器

Spring 官网定义了支持的 AspectJ 切点指示器。其中 execution 执行匹配,其余指示器限制匹配参数,注解,类型,对象。

execution(* com.example.demo.User.getUser(..))

* 表示不限定返回类型。com.example.demo是类名,User是对象名,getUser是方法名,(..)表示不限定参数。
多个指示器可以用&&,||,!组合使用。

public class LogAspect {
	@Pointcut("execution(* com.example.demo.service.MySweviceImpl.printName(..))")
	public void pointCut() {}
	
	@Before("pointCut()")
	public void before() {
		System.out.println("before ...");
	}
	
	@Around("pointCut()")
	public void around(ProceedingJoinPoint jp) {
		// 执行目标方法前的操作
		jp.proceed(); // 执行目标方法
		// 执行目标方法后的操作
	}
}

execution 表示匹配正则表达式定义的方法。com.example.demo.service.MySweviceImpl.printName是目标对象的全限定名称,可以是类,可以是方法。(..)表示任意参数。* 表示任意返回对象。
常用的匹配方法还有:@annotation():匹配带有特定注解的连接点。更多切点匹配定义参考 springboot 教程

@Before 定义前置通知。在执行目标连接点之前,先执行前置通知。

拦截方法参数

切面可以通过args指示器获取方法参数并且传递到通知中。

引入:动态添加新方法

切面可以非侵入性地为代理对象添加新方法。
HearIntroducer 是切面。它通过 @DeclareParents 注解将 Hearable 接口引入到 User bean 中。

@AspectJ
public class HearIntroducer {
    @DeclareParents(value = "com.example.demo.User+",
    				defaultImpl=DefaultHear.class)
    public static Hearable hear;
}

网站公告

今日签到

点亮在社区的每一天
去签到