详解Spring AOP
Spring AOP是Spring框架提供的一种基于代理的面向切面编程(AOP)框架,用于实现系统中的横切关注点(cross-cutting concerns)。
AOP的概念和术语
切点(Pointcut)
一个切点表示一个或多个方法,在执行这些方法时将执行相应的切面逻辑。Spring AOP使用切点来决定何时应该执行特定的切面。可以使用基于注解的方式或基于表达式的方式定义切点。
连接点(Join Point)
连接点是一个执行点,在应用程序执行过程中连接切点和相应方法的执行点。当程序执行到某个切点对应的连接点时,相应的切面逻辑就会被执行。
切面(Aspect)
切面是将通用横切关注点抽象出来并应用于连接点的一种方式。一种切面是一个横切关注点的实现,通常包括一个或多个切点和一个或多个通知。
通知(Advice)
通知是在连接点上执行的代码,在方法执行前或执行后,在方法执行异常后或方法返回结果后执行。Spring AOP提供了五种类型的通知:Before、AfterReturning、AfterThrowing、Around和After。
引入(Introduction)
一个引入允许为一个已有的Java类添加属性和方法。Spring AOP提供了两种类型的引入:接口引入和目标类字节码动态修改。
织入(Weaving)
织入是将切面应用到目标对象并创建新的代理对象的过程。Spring AOP支持三种类型的织入:编译时织入、类装载时织入和运行时织入。
Spring AOP实现示例
示例1:基于XML配置实现
配置文件
在Spring配置文件中首先需要定义各个切面。
<bean id="logAspect" class="com.example.LogAspect"/>
<bean id="securityAspect" class="com.example.SecurityAspect"/>
然后定义切点,将切面绑定到切点上。
<aop:config>
<aop:aspect id="logAspect" ref="logAspect">
<aop:pointcut id="daoLayerPointCut" expression="execution(* com.example.dao.*.*(..))"/>
<aop:before method="before" pointcut-ref="daoLayerPointCut"/>
</aop:aspect>
<aop:aspect id="securityAspect" ref="securityAspect">
<aop:pointcut id="serviceLayerPointCut" expression="execution(* com.example.service.*.*(..))"/>
<aop:around method="around" pointcut-ref="serviceLayerPointCut"/>
<aop:after-returning method="afterReturning" pointcut-ref="serviceLayerPointCut"/>
</aop:aspect>
</aop:config>
在上面的配置文件中,我们定义了两个切面,分别是LogAspect和SecurityAspect。我们使用
在点切面绑定中,我们使用
实现类
package com.example.dao;
import org.springframework.stereotype.Component;
@Component
public class UserDao {
public void save(String user) {
System.out.println("saving user: " + user);
}
}
示例2:基于注解配置实现
配置文件
<aop:aspectj-autoproxy/>
在Spring配置文件中,需要加入asop:aspectj-autoproxy节点来开启使用AspectJ自动代理功能。这个节点在系统中只需要声明一次。
切面和通知实现
在Spring AOP中,通过定义一个标注了@Aspect注解的类来声明一个切面类。
package com.example.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogAspect {
// 前置通知
@Before("execution(* com.example.dao.*.*(..))")
public void before(JoinPoint joinPoint) {
System.out.println("调用方法之前执行:" + joinPoint.getSignature().getName());
}
}
上面的代码通过使用@Aspect注解声明了一个切面LogAspect。接着,在类中定义了一个@Before注解,并在注解中传入了一个expression参数。这个参数的值是一个AOP表达式,用来表示切点。此处我们在@Before通知上的表达式表明它将应用于com.example.dao包中的所有方法。在before方法实现中,我们可以访问JoinPoint实例,从而获知当前正在执行的方法的相关信息。
被切类实现
package com.example.dao;
import org.springframework.stereotype.Component;
@Component
public class UserDao {
public void save(String user) {
System.out.println("保存用户信息:" + user);
}
}
在上述代码中,我们定义了一个UserDao类,它包含了一个保存用户信息的方法。
总结
本文介绍了Spring AOP框架的基本概念和术语,以及两个Spring AOP实现的示例。读者可以通过本文学习如何使用XML配置或注解方式来实现Spring AOP。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Spring AOP - Python技术站