国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

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

2024-07-14 08:40:36
字體:
來源:轉載
供稿:網友

在使用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之前執行@Componentpublic 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; }

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 三亚市| 四子王旗| 和静县| 石柱| 扬中市| 五大连池市| 定边县| 红河县| 伊川县| 霍城县| 敖汉旗| 湘潭县| 龙海市| 沧州市| 陆丰市| 容城县| 措美县| 西贡区| 罗城| 凤庆县| 来宾市| 万全县| 昌宁县| 梨树县| 孙吴县| 嘉义县| 武鸣县| 休宁县| 全州县| 天柱县| 长白| 左贡县| 临城县| 库伦旗| 门头沟区| 麻阳| 上犹县| 本溪| 靖安县| 巩留县| 山东|