折騰了我兩天的springboot數據源datasource循環依賴問題,都被搞瘋掉了


在做項目重構的時候增加了兩個功能

  1、多數據源。

  2、token的驗證從以前的數據庫驗證,移到了redis端。

1、多數據源使用 druid-spring-boot-starter 套件

  其核心代碼如下

  

@Configuration
public class DynamicDataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.druid.first")
    public DataSource firstDataSource(){
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.druid.second")
    public DataSource secondDataSource(){
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource) {
        Map<String, DataSource> targetDataSources = new HashMap<>();
        //targetDataSources.put(DataSourceContext.FIRST, firstDataSource);
        targetDataSources.put(DataSourceContext.SECOND, secondDataSource);
        return new DynamicDataSource(firstDataSource, targetDataSources);
    }
}

  2、token驗證規則使用spring-shiro,核心代碼如下

@Component
public class OAuth2Realm extends AuthorizingRealm {
//    @Autowired
//    private ShiroService shiroService;
    @Autowired
    private RedisTokenManager redisTokenManager;
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof OAuth2Token;
    }

    /**
     * 授權(驗證權限時調用)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//        SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal();
//        Long userId = user.getUserId();
//
//        //用戶權限列表
//        Set<String> permsSet = shiroService.getUserPermissions(userId);
//
//        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        info.setStringPermissions(permsSet);
//        return info;
        return null;
    }

    /**
     * 認證(登錄時調用)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String accessToken = (String) token.getPrincipal();
//        UsernamePasswordToken up = (UsernamePasswordToken) token;
        //根據accessToken,查詢用戶信息
        TokenModel tokenEntity = redisTokenManager.getToken(accessToken);
        //token失效
        if(tokenEntity == null ){
            throw new IncorrectCredentialsException("token失效,請重新登錄");
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(tokenEntity.getUserId(), accessToken, getName());
        return info;
//        if(tokenEntity.getType()==null||
//        	Integer.valueOf(tokenEntity.getType()).equals(Constant.LoginUserType.CUSTOM.getValue())){
//        	//查詢用戶信息
//            SysUserEntity user = shiroService.queryUser(tokenEntity.getUserId());
//            //賬號鎖定
//            if(user.getStatus() == 0){
//                throw new LockedAccountException("賬號已被鎖定,請聯系管理員");
//            }
//            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, accessToken, getName());
//            return info;
//        }else{
//        	//查詢用戶信息
//            SysUserEntity user = shiroService.queryUser(tokenEntity.getUserId());
//            //賬號鎖定
//            if(user.getStatus() == 0){
//                throw new LockedAccountException("賬號已被鎖定,請聯系管理員");
//            }
//            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, accessToken, getName());
//            return info;
//        }



    }

}

 然后啟動項目,就出現datasource循環依賴的問題。

 

The dependencies of some of the beans in the application context form a cycle:

evaluationCarService (field private io.yeliang.business.dao.EvaluationCarDao io.yeliang.business.service.impl.EvaluationCarServiceImpl.evaluationCarDao)

evaluationCarDao defined in file [D:\workspace\tmxc-parent\tmxc-order-service\target\classes\io\yeliang\business\dao\EvaluationCarDao.class]

sqlSessionFactory defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]
┌─────┐
| dataSource defined in class path resource [io/yeliang/dynamicdatasource/DynamicDataSourceConfig.class]
↑ ↓
| firstDataSource defined in class path resource [io/yeliang/dynamicdatasource/DynamicDataSourceConfig.class]
↑ ↓
| dataSourceInitializer
└─────┘

 

過程就不過了,痛苦。

結論是把

@Component
public class OAuth2Realm extends AuthorizingRealm {
//    @Autowired
//    private ShiroService shiroService;
中這兩行的注解打開就行。或隨便找個service注冊都行。
目的是讓datasource提前注冊到spring容器。

這個肯定不是好辦法,先這樣吧。受不了了。記錄一下。
有更好的辦法,歡迎留言。謝謝

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM