&内的Spring AOP不能与方法一起使用

本教程将介绍&内的Spring AOP不能与方法一起使用的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

&内的Spring AOP不能与方法一起使用 教程 第1张

问题描述

下面是我的自定义批注。

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

我想对"MyAnnotation"做些什么,所以我声明了@Around和如下所示的方法。

@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();
  }
 }
....
}

以下服务由其他类别自动提供(&Q;)。所以我认为这不是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被注释为一个类,则调用Continue(),但如果方法带有上述代码的注释,则它不起作用。我希望它只使用方法。

我尝试解决此问题的方法是什么?

推荐答案

您当前正在执行的操作与我在this answer中解释的操作类似,即匹配类的(元)批注。

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

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

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_master.app.MetaAnnotation替换为org.springframework.transaction.annotation.Transactional,它应该适用于您的用例。请确保不要打乱()@*的编号和嵌套顺序,否则很快就会出现切入点语法错误。

如果您希望使用一个或两个通知方法,您可以创建一个包含两个切入点的大而杂乱的字符串,或者定义两个单独的@Pointcut并将它们组合在通知中,用||将它们链接起来。

好了关于&内的Spring AOP不能与方法一起使用的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。