【问题标题】:NoSuchBeanDefinitionException after migrate from spring boot 1.5 to 2.0从 Spring Boot 1.5 迁移到 2.0 后出现 NoSuchBeanDefinitionException
【发布时间】:2018-09-18 21:37:25
【问题描述】:

今天我想从 spring boot 1.5.7 升级到 2.0.1,但在运行时 spring 找不到我的 ApplicationConfiguration 类之外的任何 spring-bean,即使我在 SpringBootApplication (scanBasePackages) 注释中提到了这些包。

这些是我的 pom.xml 文件版本的属性:

<properties>
    <hibernate.version>5.2.10.Final</hibernate.version>
    <spring.version>5.0.5.RELEASE</spring.version>
    <springSecurity.version>5.0.4.RELEASE</springSecurity.version>
    <springBoot.version>2.0.1.RELEASE</springBoot.version>
    <jackson.version>2.9.1</jackson.version>
    <slf4j.version>1.7.13</slf4j.version>
    <logback.version>1.1.3</logback.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

这是我的 ApplicationConfiguration 类:

package t.i.config;    

@SpringBootApplication(scanBasePackages = { 
    "t.i.DAO", 
    "t.i.SERVICES",
    "t.i.config"
})
@EnableAutoConfiguration(exclude = { 
    /*HibernateJpaAutoConfiguration.class*/ // old spring-boot 1.5 class
})
@PropertySource({ "classpath:application.mssql.properties" })
@EnableCaching
@EnableTransactionManagement
public class ApplicationConfiguration {

    @Primary
    @Autowired
    @Bean
    public LocalSessionFactoryBean sessionFactory(DataSource dataSource,
                                                  MultiTenantConnectionProvider multiTenantConnectionProviderImpl,
                                                  CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl) {

        ... code there that need MultiTenantConnectionProvider ...

    }
}

SessionFactory bean 需要 MultiTenantConnectionProvider,它存在于包 t.i.config.multitenancy:

package t.i.config.multitenancy;

@Component
public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {

   ... code there ...

}

尽管在配置类上有注解:

@SpringBootApplication(scanBasePackages = "t.i.config")

Spring 在运行时抛出异常:

NoSuchBeanDefinitionException:没有“org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider”类型的合格 bean 可用

这是 MultiTenantConnectionProvider 的一个例子,但如果没有在 ApplicationConfiguration 文件中明确声明它们,spring 找不到我的任何 bean(存储库和服务)。

也许这并不重要,但我将我的应用程序作为 jar 启动,我的 SpringBootApplicationLauncher 类处理命令行参数和上下文加载:

package t.i;

public class SpringBootApplicationLauncher {    
    public static void main(String[] args) throws Exception {
        SpringApplication springApp = new SpringApplication(new Class[]{t.i.config.ApplicationConfiguration.class});
        context = springApp.run(args);
    }
}

我错在哪里?编辑:感谢 Norbert Bicsi 的回答。

【问题讨论】:

  • 你是。真的非常努力地使事情变得非常复杂,并在配置和托管依赖项中围绕 Spring Boot 工作。在 JPA 上使用普通休眠的原因是什么?与使用 JPA 和 Hibernate 作为提供者相比,它能给您带来什么?
  • 我使用 Hibernate 会话而不是 JPA,因为我已经开始这个项目 2 年了,许多查询是用 HQL(没有 JPQL)编写的。据我了解,JPQL 不支持某些 HQL 功能,这就是为什么我需要 Hibernate 会话来进行 HQL 查询...
  • 取决于您使用的查询。尽管如此,在使用 JPA 时,您仍然可以使用普通的 Session。只是打开它。这样,您可以让 Spring Boot 自动配置您的休眠模式,并且仍然让代码与旧版 API 一起工作。基本上两全其美,你有一个迁移策略。

标签: java spring hibernate spring-boot


【解决方案1】:

由于您是在多租户应用程序中定义自己的数据源,因此您不能让 Spring Boot 发挥其自动配置数据源和连接到数据源属性中定义的数据库的魔力。

您应该排除DataSourceAutoConfiguration 类。

所以需要添加exclude属性如下:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })

我最近创建了一个带有完整源代码的基于 Spring Boot 2(带有 Hibernate)和 Spring Security 5 的每租户数据库多租户 Web 应用程序。 Take a look 如果有帮助请告诉我。

【讨论】:

    【解决方案2】:

    您可以尝试将应用程序类保留在项目的根级别的基本方法,以便@SpringBootApplication 对其旁边的所有包和所有子包进行组件扫描。

    或者您可以尝试使用组件扫描注释,例如:

    @ComponentScan(basePackages = {
        "t.i.DAO", 
        "t.i.SERVICES",
        "t.i.config"
    })
    @SpringBootApplication
    public class ApiApplication { 
        // ...
    }
    

    【讨论】:

    • 谢谢,它有效!春天能找到我的豆子!但现在我又遇到了一个问题:每次 http 调用都会出现 405 错误
    • 善待并支持并接受我的回答,如果它有效:) 并且还针对 405 错误提出另一个问题,我很确定我很清楚发生了什么。我也会回答这个问题,只是提供一些细节,发布错误并将问题链接到 cmets 中。
    • 你是对的!我是 stackoverflow 的初学者,再次感谢,我赞成您的回答,但我仍然没有 15 名声望,所以现在看不到赞成票。我在那里发布了我的新问题:stackoverflow.com/questions/49739072/…
    猜你喜欢
    • 1970-01-01
    • 2019-04-11
    • 2019-10-22
    • 1970-01-01
    • 2019-03-24
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    相关资源
    最近更新 更多