从spring boot 1.5迁移到2.0后的NoSuchBeanDefinitionException

时间:2018-04-09 13:08:02

标签: java spring hibernate spring-boot

今天我想从spring boot 1.5.7升级到2.0.1但是在运行时spring无法找到我的ApplicationConfiguration类之外的任何spring-beans,即使我在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需要包含在t.i.config.multitenancy包中的MultiTenantConnectionProvider:

package t.i.config.multitenancy;

@Component
public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {

   ... code there ...

}

尽管配置类有注释:

  

@SpringBootApplication(scanBasePackages =“t.i.config”)

运行时抛出异常:

  

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的回答。

2 个答案:

答案 0 :(得分:1)

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

您应该排除DataSourceAutoConfiguration类。

因此您需要添加exclude属性,如下所示:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })

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

答案 1 :(得分:0)

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

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

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