You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot自定义Starter不使用@EntityScan加载实体可行吗?

Spring Boot自定义Starter实体加载问题

我正在测试Spring Boot自定义Starter,除实体加载外其余配置均已完成。尝试在@AutoConfiguration类中用@Import加载实体但无效;若在Starter中使用@EntityScan,依赖该Starter的项目若自有实体,也必须添加@EntityScan,这违背了Starter自动配置的初衷——引入Starter后应无需额外操作即可使用,仅需按需覆盖配置或声明属性。

Starter自动配置类示例

@AutoConfiguration(after = JpaRepositoriesAutoConfiguration.class)
//@AutoConfigureAfter(JpaRepositoriesAutoConfiguration.class)
@EnableJpaRepositories(basePackages = "com.example.springbootstarterexample.repository")
@Import({SomeServiceImpl.class, SomeEntityController.class /*, SomeEntity.class NOT WORKING*/})
@EntityScan(basePackages = "com.example.springbootstarterexample.domain")
public class ExampleAutoConfiguration {

}

依赖Starter的消费端配置情况

场景1:Starter中使用@EntityScan时

消费端需添加自身实体扫描配置:

@SpringBootApplication
@EntityScan(basePackages = "com.example.springbootconsumer.model")
public class SpringBootConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootConsumerApplication.class, args);
    }

}

场景2:移除Starter中的@EntityScan时

消费端必须同时指定自身和Starter的实体包路径:

@SpringBootApplication
@EntityScan(basePackages = {"com.example.springbootconsumer.model", "com.example.springbootstarterexample.domain"})
public class SpringBootConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootConsumerApplication.class, args);
    }

}

这完全破坏了自动配置,因为消费端必须知晓Starter中实体的位置才能启动应用。


编辑1:尝试使用@AutoConfigurationPackage

配置类调整如下:

@AutoConfiguration(after = JpaRepositoriesAutoConfiguration.class)
//@AutoConfigureAfter(JpaRepositoriesAutoConfiguration.class)
//@EnableJpaRepositories(basePackages = {"com.example.springbootstarterexample.repository"})
@AutoConfigurationPackage(basePackageClasses = {SomeEntity.class, SomeEntityRepository.class})
@Import({SomeServiceImpl.class, SomeEntityController.class /*, SomeEntity.class NOT WORKING*/})
//@EntityScan(basePackages = "com.example.springbootstarterexample.domain")
public class ExampleAutoConfiguration {

}

此时无法实例化Repository,报错:

Description:

Parameter 0 of constructor in com.example.springbootstarterexample.service.SomeServiceImpl required a bean of type 'com.example.springbootstarterexample.repository.SomeEntityRepository' that could not be found.


Action:

Consider defining a bean of type 'com.example.springbootstarterexample.repository.SomeEntityRepository' in your configuration.

若添加@EnableJpaRepositories,可找到Repository但无法识别实体:

@AutoConfiguration(after = JpaRepositoriesAutoConfiguration.class)
//@AutoConfigureAfter(JpaRepositoriesAutoConfiguration.class)
@EnableJpaRepositories(basePackages = {"com.example.springbootstarterexample.repository"})
@AutoConfigurationPackage(basePackageClasses = {SomeEntity.class})
@Import({SomeServiceImpl.class, SomeEntityController.class /*, SomeEntity.class NOT WORKING*/})
//@EntityScan(basePackages = "com.example.springbootstarterexample.domain")
public class ExampleAutoConfiguration {

}

错误信息:

Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.example.springbootstarterexample.domain.SomeEntity

使用包名配置也得到相同结果。


编辑2:通过META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports加载配置类

移除@Import,配置类如下:

@AutoConfiguration(after = JpaRepositoriesAutoConfiguration.class)
//@AutoConfigureAfter(JpaRepositoriesAutoConfiguration.class)
//@EnableJpaRepositories(basePackages = {"com.example.springbootstarterexample.repository"})
@AutoConfigurationPackage(basePackageClasses = {SomeEntity.class, SomeServiceImpl.class, SomeEntityController.class, SomeEntityRepository.class})
//@Import({SomeServiceImpl.class, SomeEntityController.class /*, SomeEntity.class NOT WORKING*/})
//@EntityScan(basePackages = "com.example.springbootstarterexample.domain")
public class ExampleAutoConfiguration {

}

消费端尝试注入Bean时报错:

Description:

Parameter 0 of constructor in com.example.springbootconsumer.SpringBootConsumerApplication required a bean of type 'com.example.springbootstarterexample.service.SomeService' that could not be found.


Action:

Consider defining a bean of type 'com.example.springbootstarterexample.service.SomeService' in your configuration.

似乎未加载任何配置。


编辑3:调整包结构并开启TRACE日志

将所有类放在ExampleAutoConfiguration所在的同一包下,配置类如下:

@AutoConfiguration(after = JpaRepositoriesAutoConfiguration.class)
//@AutoConfigureAfter(JpaRepositoriesAutoConfiguration.class)
//@EnableJpaRepositories(basePackages = {"com.example.springbootstarterexample.repository"})
@AutoConfigurationPackage
//@Import({SomeServiceImpl.class, SomeEntityController.class /*, SomeEntity.class NOT WORKING*/})
//@EntityScan(basePackages = "com.example.springbootstarterexample.domain")
public class ExampleAutoConfiguration {

}

日志显示@AutoConfiguration类已被扫描,但未找到包中定义的任何Bean:

2022-09-08 20:03:24.495 TRACE 17132 --- [           main] a.ConfigurationClassBeanDefinitionReader : Registered bean definition for imported class 'com.example.springbootstarterexample.autoconfigure.ExampleAutoConfiguration'

而使用常规配置时,所有Bean都会被创建:

2022-09-08 22:31:34.580 TRACE 2308 --- [           main] a.ConfigurationClassBeanDefinitionReader : Registered bean definition for imported class 'com.example.springbootstarterexample.service.SomeServiceImpl'
2022-09-08 22:31:34.581 TRACE 2308 --- [           main] a.ConfigurationClassBeanDefinitionReader : Registered bean definition for imported class 'com.example.springbootstarterexample.controller.SomeEntityController'
2022-09-08 22:31:34.585 TRACE 2308 --- [           main] a.ConfigurationClassBeanDefinitionReader : Registered bean definition for imported class 'com.example.springbootstarterexample.autoconfigure.ExampleAutoConfiguration'
2022-09-08 22:31:34.685 TRACE 2308 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Spring Data JPA - Registering repository: someEntityRepository - Interface: com.example.springbootstarterexample.repository.SomeEntityRepository - Factory: org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean
2022-09-08 22:31:39.094 DEBUG 2308 --- [           main] org.hibernate.cfg.Ejb3Column             : Binding column: Ejb3DiscriminatorColumn{logicalColumnName'DTYPE', discriminatorTypeName='string'}
2022-09-08 22:31:39.112 DEBUG 2308 --- [           main] o.h.cfg.annotations.EntityBinder         : Import with entity name SomeEntity
2022-09-08 22:31:39.113 TRACE 2308 --- [           main] o.h.b.i.InFlightMetadataCollectorImpl    : Import: SomeEntity -> com.example.springbootstarterexample.domain.SomeEntity
2022-09-08 22:31:39.114 TRACE 2308 --- [           main] o.h.b.i.InFlightMetadataCollectorImpl    : Import: com.example.springbootstarterexample.domain.SomeEntity -> com.example.springbootstarterexample.domain.SomeEntity

内容的提问来源于stack exchange,提问作者Pp88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:36:16