美文网首页
Spring AOP 切点 (Pointcut)

Spring AOP 切点 (Pointcut)

作者: Tinyspot | 来源:发表于2023-12-13 19:36 被阅读0次

1. 切面 (Aspect)

  • 切面,切入点和通知的抽象,定义切入点和通知
  • @Aspect 声明当前类是一个切面

1.1 Advice 注解

  • @Before
  • @Around
  • @After
  • @AfterReturning
  • @AfterThrowing
@Aspect
@Component
public class LoggerAspect {

    @Around(value = "execution(* com.example.concrete.starter.service.*.*(..))")
    public Object aroundCut(ProceedingJoinPoint point) throws Throwable {
        System.out.println("around...");
        return point.proceed();
    }
}

1.2 切点 + 增强

  • @Pointcut("匹配规则")
  • @Pointcut:
@Aspect
@Component
public class LogCut {
    // 定义切点
    @Pointcut(value = "execution(* com.example.concrete.starter.service.*.*(..))")
    public void pointCut() {}

    @Before(value = "pointCut()")
    public void before(JoinPoint joinPoint) {
      // ...
    }
}

2. 注解拦截

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnno {
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AfterAnno {
}

2.1 拦截类下面所有方法

@LogAnno
@AfterAnno
@Service
public class GreetServiceImpl implements GreetService {

    @Override
    public String greeting(UserDTO userDTO, String env) {
        return "greeting run..." + JSON.toJSONString(userDTO) + "; " + env;
    }
}
@Aspect
@Component
public class LoggerAspect {

    @Pointcut("@annotation(com.example.concrete.starter.intercept.aop.LogAnno)")
    public void pointCut() {}

    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("before...");
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("around start");
        Object obj = point.proceed();
        System.out.println("around end");
        return obj;
    }

    @Pointcut("@annotation(com.example.concrete.starter.intercept.aop.AfterAnno)")
    public void afterCut() {}
    // 复合切点
    @After("pointCut() && afterCut()")
    public void after() {
        System.out.println("after...");
    }

}

22. 拦截方法

@Service
public class GreetServiceImpl implements GreetService {

    @Override
    @LogAnno
    @AfterAnno
    public String greeting(UserDTO userDTO, String env) {
        return "greeting run..." + JSON.toJSONString(userDTO) + "; " + env;
    }
}

3. 表达式拦截

@Aspect
@Component
public class ExecutionAspect {

    @AfterReturning(value = "execution(* com.example.concrete.starter.service.*.*(..))", returning = "result")
    public void AfterReturning(JoinPoint joinPoint, Object result) {
        Object[] args = joinPoint.getArgs();
        System.out.println("after returning: " + JSON.toJSONString(args));
        System.out.println("after result: " + JSON.toJSONString(result));
    }
}

3.1 切入点表达式

  • 格式 execution([修饰符] 返回值类型 包名.类名.方法名(参数))
  • .*.* 表示所有包的所有方法,(..) 方法参数
# 匹配 GreetServiceImpl#greet
execution(public String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(Integer))

# 匹配 GreetServiceImpl 类的任意 greet 方法
execution(* com.example.concrete.starter.service.impl.GreetServiceImpl.greet(..))

# 匹配 GreetServiceImpl 类的所有方法
execution(* com.example.concrete.starter.service.impl.GreetServiceImpl.*(..))

# 匹配 service 包 (包含子包) 所有 public 方法
execution(public * com.example.concrete.starter.service.*.*(..))

# 匹配 service 包 (包含子包) 所有类的所有方法
execution(* com.example.concrete.starter.service.*.*(..))

# 可选:匹配 service 包及其子包,两个点(..)
execution(* com.example.concrete.starter.service..*.*(..))

4. XML 配置方式

  • 官方文档 https://docs.spring.io/spring-framework/docs/3.0.x/reference/aop.html
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        https://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        https://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 开启自动扫描 -->
    <context:component-scan base-package="com.example.concrete.starter"/>
    <!-- 配置 AOP 代理 -->
    <aop:aspectj-autoproxy/>

</beans>
<aop:config>
  <aop:aspect id="myAspect" ref="aspectBeanName">
    <aop:pointcut id="pointcutMethodName" expression="execution(* com.example.concrete.service..*.*(..))" />
    <aop:before method="beforMethodName" pointcut-ref="pointcutMethodName" />
  <aop:aspect>
</aop:config>

相关文章

网友评论

      本文标题:Spring AOP 切点 (Pointcut)

      本文链接:https://www.haomeiwen.com/subject/tkqigdtx.html