Spring框架中的AOP详解
Spring框架中的AOP详解
Spring框架中的AOP(面向切面编程)是一种编程思想,旨在通过将横切关注点(cross-cutting concerns)从业务逻辑中分离出来,提高代码的可重用性、可维护性和模块化程度。
AOP的底层实现依赖于动态代理机制,AOP框架会动态生成一个代理对象。这个代理对象在方法调用时会拦截目标方法的执行,并根据切入点表达式判断是否需要执行通知逻辑。如果需要执行通知逻辑,AOP框架会在目标方法执行前、执行后或抛出异常时等时机插入相应的通知代码。因此,在Spring中AOP是依赖于IoC的,所以要将切面类交给Spring容器去管理,而AOP的作用就是在不改变原有代码的基础上,做出一些扩展。
AOP的实现
AOP的实现首先是需要一个类上加上@Aspect
注解,并将这个类注入到Spring容器中管理,而这个类就叫切面类(这个类确定了要在程序哪个面进行切入)。
然后在切面类中创建方法加入需要增强的代码块,在这个方法上添加合适的通知方法,并确定切点表达式,明确指出要将代码增强到哪些方法中。我们还可以通过JoinPoint
获取目标方法的信息(比如切入点的对象,方法,属性等。)并在AOP通知中执行特定的逻辑。
我们首先创建一个切面类,@Aspect
注解标记为切面类,@Component
注解注入到Spring容器。
添加一个log方法,在这个方法上加上@Before
前置通知注解,并给这个方法设置切入点,告诉这个切面类在哪个切入点执行。
可以通过JoinPoint
来获取目标方法的信息。
我们除了可以加前置通知(Before advice)还可以写后置通知(After advice)、异常通知(After throwing advice)和返回通知(After returning advice)、环绕通知(Around advice)。
在环绕通知中我们需要注意一点,ProceedingJoinPoint
是JoinPoint
的子接口,它继承自JoinPoint
的所有方法。proceed()
是最重要的方法,用于继续执行被通知的方法。如果环绕通知中不调用此方法,被通知的方法将不会执行。
关于后置通知和返回通知,返回通知是在后置通知之前执行的。而异常通知只有在发生异常之后才会执行。
切点表达式
我们如果想匹配com.example.service
包下所有类的所有public方法可以写:
execution(public * com.example.service…*(…))
execution
:表示这是一个方法执行的切点。这里面有四个参数,public
表示匹配所有public方法(如果不写代表匹配所有的)、*
返回类型任意、com.example.service…*
表示com.example.service
包及其子包下的所有类、(…)
表示方法参数任意。
比如匹配com.example.service
包下所有类的所有以String为参数的方法:
execution(* com.example.service…*(String))
除了execution
表达式之外还有@annotation()
,@annotation()
可以通过反射机制来检查某个类、方法、字段等是否被某个特定的注解标记,获取该注解的详细信息时。这里会获取到@Log
注解实例并得到value值。