&内的Spring AOP不能与方法一起使用
下面是我的自定义批注。
@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
并将它们组合在通知中,用||
将它们链接起来。
相关文章