1.プロジェクトの概要
mybatis-plus-boot-starterの依存関係がプロジェクトで使用されます。データパーミッションの同じ処理を実現するために、mybatisのインターセプターインターフェイスを実装するデータパーミッションインターセプターがカスタマイズされます(パブリッククラスDataScopeInterceptorはインターセプターを実装します)。シロは、許可処理のためのプロジェクトでも使用されています。
2.分析
ShiroFilterFactoryBeanはBeanPostProcessorインターフェース(スプリング拡張インターフェース)を実装しているため、プロジェクトの開始時にBeanのインスタンスが最初に作成されます。ShiroFilterFactoryBeanのSecurityManagerのShiroRealmは、カスタムレルム(ShiroRealm)です。
ShiroRealmはAserviceなどのカスタムサービスを注入し、AserviceはAmapperを注入しました。すべてのマッパーはSqlSessionFactoryに注入されるため、プロジェクトの開始時にBeanをロードするプロセスは次のとおりです。
ShiroFilterFactoryBean "SecurityManager" ShiroRealm "Aservice" Amapper "SqlSessionFactory、およびMybatisPlusAutoConfigurationは、SqlSessionFactoryの作成時にロードされます。ここで注意すべき問題があります。つまり、SqlSessionFactory BeanがSpringの3レベルキャッシュsingletonFactoriesに配置されず、MybatisPlusAutoConfigurationをロードします。すべてのインターセプターがロードされ、インターセプターDataScopeInterceptorにBserviceが注入され、BserviceにBmapperが注入されるため、Beanのロードプロセス全体は次のようになります。
ShiroFilterFactoryBean》 SecurityManager》 ShiroRealm》 Aservice》 Amapper》SqlSessionFactory》 MybatisPlusAutoConfiguration》 DataScopeInterceptor》 Bservice》 Bmapper》SqlSessionFactory
SqlSessionFactoryが初めてロードされ、Springの第3レベルキャッシュのsingletonFactoriesに配置されないため、SqlSessionFactoryが再度ロードされます。Beanが作成されるたびに、次の処理が実行されます。
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
したがって、このメソッドは、最初にSqlSessionFactoryが作成されたときに成功しましたが、2回目は、singletonsCurrentlyInCreationにすでにSqlSessionFactoryが存在するため、BeanCurrentlyInCreationExceptionがスローされました。
三、解決策
最初の解決策(推奨):DataScopeInterceptorが依存するBserviceに@Lazyを追加します
2番目の解決策:BserviceをAserviceの最初の依存関係に配置します。Bserviceは使用されませんが、DataScopeInterceptorの後にBmapperが作成されなくなるという考え方です。もちろん、DataScopeInterceptorには他のマッパーはありません。
4、まとめ
SqlSessionFactory "MybatisPlusAutoConfiguration、およびSqlSessionFactoryはSpringの3レベルキャッシュのsingletonFactoriesに配置されないため、MybatisPlusAutoConfigurationの読み込みが完了する前に、SqlSessionFactoryを再度読み込むことはできません。つまり、他のマッパーを読み込むことはできません。