91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解決Spring聲明式事務和@Aspect的攔截順序的問題

發布時間:2021-07-28 14:36:59 來源:億速云 閱讀:483 作者:小新 欄目:編程語言

這篇文章主要介紹了如何解決Spring聲明式事務和@Aspect的攔截順序的問題,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

在使用AbstractRoutingDataSource配置多數據源時,發現使用@aspect配置的DataSourceSwitchAspect總是在聲明式事務之后執行,配置了Order依然不行,經過調研發現是由于兩者的aop代理方式不一致導致。

在spring內部,是通過BeanPostProcessor(《spring 攻略》一書中翻譯為,后處理器)來完成自動創建代理工作的。根據匹配規則的不同大致分為三種類別: 1、匹配Bean的名稱自動創建匹配到的Bean的代理,實現類BeanNameAutoProxyCreator 2、根據Bean中的AspectJ注解自動創建代理,實現類AnnotationAwareAspectJAutoProxyCreator 3、根據Advisor的匹配機制自動創建代理,會對容器中所有的Advisor進行掃描,自動將這些切面應用到匹配的Bean中,實現類DefaultAdvisorAutoProxyCreator

其中@Aspect聲明的aop是通過AnnotationAwareAspectJAutoProxyCreator進行代理的,而項目中的聲明式事務是BeanNameAutoProxyCreator方式進行代理的,經調試發現BeanNameAutoProxyCreator攔截優先級高于AnnotationAwareAspectJAutoProxyCreator,order配置只對同一類型的aop攔截方式起作用,如下:

DataSourceSwitchAspect

/**
 * 數據源切換切面
 * @author Matchstick
 */
@Aspect
@Order(1) //確保該切面在transaction之前執行
@Component
public class DataSourceSwitchAspect
{
 private Logger logger = LoggerFactory.getLogger(getClass());
 
 @Pointcut("@annotation(com.etu.multidatasource.test.datasource.DataSourceId)")
 public void pointcut(){}
 
 @Before("@annotation(dataSourceId)")
 public void switchDataSource(JoinPoint point, DataSourceId dataSourceId)
 {
 String dsId = dataSourceId.value();
 MultiDataSourceContextHolder.setDataSourceId(dsId);
 logger.debug("switch datasource -> {}", dsId);
 }

 @After("@annotation(dataSourceId)")
 public void restoreDataSource(JoinPoint point, DataSourceId dataSourceId)
 {
 MultiDataSourceContextHolder.removeDataSourceId();
 logger.debug("restore datasource -> {}",         MultiDataSourceContextHolder.getDefaultDataSourceId());
 }
}

DataSourceConfig

@Bean
 public BeanNameAutoProxyCreator txProxy()
 {
 BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
 creator.setInterceptorNames("txAdvice");
 creator.setBeanNames("*Service", "*ServiceImpl");
 creator.setProxyTargetClass(true);
 creator.setOrder(2);
 return creator;
 }

解決方案:要么修改DataSourceSwitchAspect的aop方式為BeanNameAutoProxyCreator,要么修改事務aop方式為AnnotationAwareAspectJAutoProxyCreator,由于是通過注解實現的數據源切換aop,所以選擇了后者解決方案,如下:

DataSourceConfig

@Bean
 public AnnotationAwareAspectJAutoProxyCreator txProxy()
 {
 /*
  * 必須使用AspectJ方式的AutoProxy,這樣才能和DataSourceSwitchAspect保持統一的aop攔截方式,否則不同的攔截方式會導致order失效
  */
 AnnotationAwareAspectJAutoProxyCreator c = new AnnotationAwareAspectJAutoProxyCreator();
 c.setInterceptorNames("txAdvice");
 c.setIncludePatterns(Arrays.asList("execution (public com.etu..*Service(..))"));
 c.setProxyTargetClass(true);
 c.setOrder(2);
 return c;
 }

感謝你能夠認真閱讀完這篇文章,希望小編分享的“如何解決Spring聲明式事務和@Aspect的攔截順序的問題”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

唐山市| 江孜县| 鹿邑县| 通海县| 丰宁| 壤塘县| 全州县| 财经| 武川县| 榆中县| 江安县| 广水市| 石嘴山市| 大连市| 汶川县| 娄底市| 淳化县| 元阳县| 同德县| 盘山县| 东辽县| 常熟市| 望都县| 屏边| 仁布县| 鹰潭市| 新建县| 房山区| 西吉县| 炎陵县| 德保县| 平顺县| 兴业县| 阳原县| 双峰县| 玛纳斯县| 宝山区| 靖边县| 乌审旗| 通山县| 平南县|