本文介紹了&內(nèi)的Spring AOP不能與方法一起使用的處理方法,對(duì)大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
下面是我的自定義批注。
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Transactional(value = TransactionalCode.MANAGER, readOnly = true)
public @interface FinanceReadTx {
}
我想對(duì)";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();
}
}
....
}
以下服務(wù)由其他類別自動(dòng)提供(&Q;)。所以我認(rèn)為這不是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;
}
...
}
下面的代碼調(diào)用上述服務(wù)
@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
被注釋為一個(gè)類,則調(diào)用Continue(),但如果方法帶有上述代碼的注釋,則它不起作用。我希望它只使用方法。
我嘗試解決此問題的方法是什么?
推薦答案
您當(dāng)前正在執(zhí)行的操作與我在this answer中解釋的操作類似,即匹配類的(元)批注。
現(xiàn)在您想知道為什么它不匹配方法。我解釋了here。基本上,@within()
匹配帶注釋的類中的任何內(nèi)容,而@annotation()
匹配帶注釋的方法。問題是,@annotation()
需要一個(gè)確切的類型名稱。
但是有另一種方法可以直接在execution()
簽名中表示帶注釋的方法。在這里,您還可以選擇以與對(duì)帶注釋的類使用元注釋類似的方式指定元注釋。讓我們將兩者進(jìn)行比較:
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
,它應(yīng)該適用于您的用例。請(qǐng)確保不要打亂()
、@
和*
的編號(hào)和嵌套順序,否則很快就會(huì)出現(xiàn)切入點(diǎn)語(yǔ)法錯(cuò)誤。
如果您希望使用一個(gè)或兩個(gè)通知方法,您可以創(chuàng)建一個(gè)包含兩個(gè)切入點(diǎn)的大而雜亂的字符串,或者定義兩個(gè)單獨(dú)的@Pointcut
并將它們組合在通知中,用||
將它們鏈接起來。
這篇關(guān)于&內(nèi)的Spring AOP不能與方法一起使用的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,