📅  最后修改于: 2023-12-03 15:20:12.388000             🧑  作者: Mango
Spring AOP(面向切面编程)是Spring框架的一个重要组成部分,它通过动态代理技术在程序运行时动态地将切面织入到目标对象的方法中,从而实现对目标对象的增强,比如添加日志、性能统计、事务控制等。
在Spring AOP中,PointCut(切入点)是指定义拦截哪些方法的一种方式,它通过匹配方法名、返回类型、参数列表等信息来确定哪些方法需要被拦截。
Spring AOP提供了多种定义PointCut的方式,其中比较常用的一种是基于注释的PointCut。这种方式非常灵活,可以根据不同的注释来定义不同的PointCut。
我们可以通过定义一个注释来表示一个切面的功能。比如我们定义一个注释@ServiceLog
来表示需要记录服务日志的方法。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ServiceLog {
String value() default "";
}
这个注释有一个可选参数value
,表示日志内容。我们可以在使用注释时指定这个参数:
@Service
public class UserServiceImpl implements UserService {
@ServiceLog("添加用户")
@Override
public void addUser(User user) {
// 添加用户逻辑
}
}
定义好注释之后,我们需要用一个切面来表示对这个注释的处理。比如我们定义一个切面ServiceLogAspect
来记录服务日志。
@Aspect
@Component
public class ServiceLogAspect {
@Around("@annotation(com.example.ServiceLog)")
public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
ServiceLog serviceLog = getAnnotation(pjp);
String logContent = serviceLog.value();
// 记录日志
Object result = pjp.proceed();
// 记录结果
return result;
}
private ServiceLog getAnnotation(ProceedingJoinPoint pjp) {
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
return methodSignature.getMethod().getAnnotation(ServiceLog.class);
}
}
这个切面使用@Around
注释表示它是一个AroundAdvice,会在拦截到匹配的方法时执行。它使用@annotation
指示器来匹配被注释的方法,并使用getAnnotation
方法从方法签名中取出注释实例。
最后,我们需要在Spring的配置文件中配置这个切面。
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="serviceLogAspect" class="com.example.ServiceLogAspect"></bean>
<aop:aspectj-autoproxy>
指示Spring启用AspectJ自动代理。<bean id="serviceLogAspect" class="com.example.ServiceLogAspect"></bean>
定义了切面实例。
使用基于注释的PointCut可以非常灵活地定义切入点,并且不会污染业务代码。它是Spring AOP中常用的定义PointCut的方式之一。