当前位置: 首页 > 知识库问答 >
问题:

Spring AOP“in”不适用于方法

孙京
2023-03-14

下面是我的自定义注释。

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Transactional(value = TransactionalCode.MANAGER, readOnly = true)
public @interface FinanceReadTx {
}

我想用“MyAnnoation”做点什么,所以我声明@周围和如下方法。

@Aspect
@Component
public class TransactionalInterceptor implements Ordered {
    @Around("within(@org.springframework.transaction.annotation.Transactional *) || " +
            "within(@(@org.springframework.transaction.annotation.Transactional *) *)")
    public Object proceed(ProceedingJoinPoint pjp) throws Throwable {
        try {
            setDbType(pjp);
            Object result = pjp.proceed();
            DataSourceContextHolder.clearDataSourceType();
            return result;
        } finally {
            // restore state
            DataSourceContextHolder.clearDataSourceType();
        }
    }
....
}

下面的服务被其他类“自动安装”。所以我认为这不是与AOP代理相关的问题。

@Service
public class UnconfirmedReportService {
    private static final int PREVIEW_SIZE = 8;
    @Autowired
    private UnconfirmedReportRepository unconfirmedReportRepository;
...
    @FinanceHikariReadTx
    public List<UnconfirmedExcelDownloadView> getExcelData(UnconfirmedSearchCondition condition) {
        List<UnconfirmedExcelDownloadView> excelData = newArrayList();
        excelData.addAll(newArrayList(getPurchaseReportDetailExcel(condition)));
        return excelData;
    }
...
}

下面的代码调用上面的服务

@Slf4j
@Component
public class UnconfirmedDashboardDetailExcelReader extends SellerExcelReaderTemplate<UnconfirmedExcelDownloadView, UnconfirmedSearchCondition> {
    @Autowired
    private UnconfirmedReportService unconfirmedReportservice;

    @Override public List<UnconfirmedExcelDownloadView> read(String conditionJson) {
        UnconfirmedSearchCondition condition = transformCondition(conditionJson);
        List<UnconfirmedExcelDownloadView> viewList = unconfirmedReportservice.getExcelData(condition);
        return viewList;
    }
...
}

如果将@MyAnnotation注释到一个类,则会调用procedure(),但如果一个方法带有类似于上述代码的注释,则该方法不起作用。我希望它只使用方法。

我想解决什么?

共有1个答案

邓阳炎
2023-03-14

您目前正在做类似于我在这个答案中解释的事情,即在类上匹配(元)注释。

现在你想知道为什么它不匹配方法。我在这里解释过了。基本上,@in()匹配带注释类中的任何内容,而@Nonotion()匹配带注释的方法。问题是,@Nonotion()需要一个确切的类型名称。

但是有另一种方法可以直接在签名中表达带注释的方法。在这里,您还可以选择以与在注释类中使用元注释类似的方式指定元注释。让我们比较一下这两者:

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class MetaAnnotationInterceptor {
  @Before(
    "execution(* *(..)) && (" +
      "within(@de.scrum_master.app.MetaAnnotation *) || " +
      "within(@(@de.scrum_master.app.MetaAnnotation *) *) || " +
      "within(@(@(@de.scrum_master.app.MetaAnnotation *) *) *)" +
    ")"
  )
  public void annotatedClasses(JoinPoint thisJoinPoint){
    System.out.println(thisJoinPoint);
  }

  @Before(
    "execution(@de.scrum_master.app.MetaAnnotation * *(..)) || " +
    "execution(@(@de.scrum_master.app.MetaAnnotation *) * *(..)) || " +
    "execution(@(@(@de.scrum_master.app.MetaAnnotation *) *) * *(..)) "
  )
  public void annotatedMethods(JoinPoint thisJoinPoint){
    System.out.println(thisJoinPoint);
  }
}

后者就是你要找的。只需更换de.scrum\u master即可。应用程序。元注释由组织提供。springframework。交易注释。事务性的,它应该适用于您的用例。请确保不要弄乱()@*的编号和嵌套顺序,否则很快就会出现切入点语法错误。

如果您更喜欢使用一个或两个建议方法,您可以创建一个包含两个切入点的大混乱字符串,或者定义两个单独的@PointCut并将它们组合在建议中,将它们与||链接。

 类似资料:
  • 您好,我正在尝试使用PostConstruct方法初始化字段,但在测试中,此方法不会填充bidiMap字段。 有没有办法模拟字段,它是的字段? 测试: 正在测试的类:

  • 起初,我在使用< code>writeAndFlush(...)直到我偶然发现了这个修复。现在,我已经可以使用< code>writeAndFlush(...)每个字符串都带有后缀/r/n。当我尝试发送< code>ByteBuf对象时,问题仍然存在。显然,我不能只在消息末尾添加/r/n。对此有什么解决办法吗? 如果有帮助,我将使用

  • 问题内容: 由于某些原因,当我尝试从BytesIO流制作图像时,它无法识别该图像。这是我的代码: 以及它引发的错误的堆栈跟踪: 我正在使用PIL的Pillow实现。 问题答案: 将BytesIO视为文件对象,在完成图像写入后,文件的光标位于文件的末尾,因此当尝试调用时,它将立即获得EOF。 您需要添加一个经过之前到。

  • 问题内容: 当仅使用IN运算符时,以下查询工作正常 但是当我触发这个查询时,它给我一个空白的结果 我是在做错事还是其他人遇到了同样的问题? 问题答案: 我认为您必须将“ IN”条件放在括号中才能使其起作用: 它与N1QL处理器评估操作员的优先级有关 如果使用EXPLAIN关键字运行它,它将显示它如何相互链接条件。 例如 与

  • 我最近开始缓存一个方法的结果。我使用@Cacheable和@CachePut来实现所需的功能。 但不知何故,save操作并没有更新findAll方法的缓存。以下是相同的代码段: 对于findAll方法的第一个调用,它将结果存储在“persons”缓存中,对于所有后续调用,它将返回相同的结果,即使在两者之间执行了save()操作。 我对缓存很陌生,所以任何关于这方面的建议都会很有帮助。 谢谢

  • 问题内容: 嗨,我只是简单地尝试在www.example.com上获取h1标签,该标签显示为“ Example Domain”。该代码适用于http://www.example.com,但不适用于https://www.exmaple.com。我该如何解决这个问题?谢谢 问题答案: PhantomJSDriver不支持(所有)DesiredCapabilities。 你会需要: 记录在这里:htt