添加DataSourceConfig后Spring Boot项目启动失败,Autowired注入报错
我来帮你排查这个问题,看起来是添加自定义DataSourceConfig配置类后,引发了Spring Data JPA Repository Bean的生成异常,导致AdministratorController无法注入依赖。下面是具体的原因分析和解决方法:
问题重现
之前项目运行正常,添加DataSourceConfig配置类并调整pom.xml后,启动报错,核心错误信息如下:
2018-01-16 20:06:14.219 WARN 22672 --- [ main] ationConfigEmbeddedWebApplicationContext : 上下文初始化期间遇到异常 - 取消刷新尝试:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'administratorController'的Bean时出错:通过字段'administratorRepository'表达的依赖不满足;嵌套异常为org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到类型为'com.nuclibrarybackstage.repository.AdministratorRepository'的合格Bean:期望至少有1个符合自动注入候选条件的Bean。依赖注解:{@org.springframework.beans.factory.annotation.Autowired(required=true)}
原因分析
1. @EnableJpaRepositories未指定Repository扫描路径
你在DataSourceConfig中添加了@EnableJpaRepositories注解,但没有配置basePackages属性。Spring Data JPA需要明确知道要扫描哪个包下的Repository接口才能生成代理Bean,缺少这个配置的话,Spring无法发现AdministratorRepository。
2. Repository接口上的注解使用错误
AdministratorRepository上标注了@Component和@ConfigurationProperties(prefix = "administrator"),这两个注解完全不适合Spring Data JPA的Repository接口:
@Component是通用组件注解,但Spring Data JPA是通过动态代理机制生成Repository实例,不需要手动添加这个注解;@ConfigurationProperties用于绑定配置文件属性到Java类,和Repository接口毫无关系,属于错误使用。
3. 自定义数据源与Spring Boot自动配置冲突
你的DataSourceConfig中手动创建了嵌入式HSQL数据源,但pom.xml中引入了MySQL驱动,说明原本项目应该使用MySQL数据库。自定义的数据源覆盖了Spring Boot的自动配置,可能导致后续JPA的实体扫描、事务管理等功能异常。
4. Hibernate版本依赖冲突
pom.xml中手动引入了hibernate-core和hibernate-entitymanager的4.1.4版本,而spring-boot-starter-data-jpa已经依赖了适配当前Spring Boot版本的Hibernate。手动指定低版本Hibernate会引发依赖冲突,导致JPA相关功能无法正常工作。
解决方法
方法一:修正DataSourceConfig配置
如果确实需要自定义数据源配置,按照以下步骤修改:
- 指定Repository扫描路径
在@EnableJpaRepositories注解中添加basePackages属性,告诉Spring要扫描的Repository包:
@Configuration @EnableJpaRepositories(basePackages = "com.nuclibrarybackstage.repository") // 关键:指定Repository所在包 @EnableTransactionManagement public class DataSourceConfig { // 如果原本使用MySQL,替换为MySQL数据源配置(示例用Druid) @Bean public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/your_db_name"); dataSource.setUsername("root"); dataSource.setPassword("your_db_password"); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); return dataSource; } @Bean public EntityManagerFactory entityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("com.nuclibrarybackstage.domain"); // 确保实体类包路径正确 factory.setDataSource(dataSource()); factory.afterPropertiesSet(); return factory.getObject(); } @Bean public PlatformTransactionManager transactionManager() { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory()); return txManager; } }
- 移除Repository上的错误注解
只需要让AdministratorRepository继承JpaRepository即可,Spring Data JPA会自动生成代理Bean:
// 移除@Component和@ConfigurationProperties,仅保留继承关系 public interface AdministratorRepository extends JpaRepository<Administrator, Integer> { }
方法二:移除自定义DataSourceConfig,使用Spring Boot自动配置
如果没有特殊的数据源需求,推荐直接删除DataSourceConfig类,依赖Spring Boot的自动配置:
- 在配置文件中添加MySQL配置
在application-dev.properties(或application.yml)中配置数据库连接:
# 数据源配置 spring.datasource.url=jdbc:mysql://localhost:3306/your_db_name?useUnicode=true&characterEncoding=utf8&useSSL=false spring.datasource.username=root spring.datasource.password=your_db_password spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.type=com.alibaba.druid.pool.DruidDataSource # JPA配置 spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
- 在启动类上添加扫描注解
如果启动类不在项目根包(com.nuclibrarybackstage)下,需要明确指定Repository和实体类的扫描路径:
@SpringBootApplication @EnableJpaRepositories(basePackages = "com.nuclibrarybackstage.repository") @EntityScan(basePackages = "com.nuclibrarybackstage.domain") public class NucLibraryBackstageApplication { public static void main(String[] args) { SpringApplication.run(NucLibraryBackstageApplication.class, args); } }
方法三:修复Hibernate依赖冲突
移除pom.xml中手动引入的Hibernate依赖,因为spring-boot-starter-data-jpa已经包含了适配版本的Hibernate:
<!-- 移除以下两个依赖 --> <!-- <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.1.4.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.1.4.Final</version> </dependency> -->
验证步骤
- 按照上述方法修改代码和配置;
- 执行
mvn clean install清理并重新构建项目; - 启动应用,检查是否还存在Bean找不到的错误。
内容的提问来源于stack exchange,提问作者aolish




