【问题标题】:Using Prototype scope to create DataSource使用 Prototype 作用域创建 DataSource
【发布时间】:2022-11-18 20:17:45
【问题描述】:

我正在尝试使用给定的配置创建一个 Prototype Scope Spring bean。 url、用户名、密码、驱动程序的详细信息将在运行时确定。这是我的配置:

@Configuration
class Cfg {
    @Bean
    public Function<DataSourcePropertiesMap, DriverManagerDataSource> functionOfDriverMgrDS() {
        return this::driverManagerDataSource;
    }

    @Lazy
    @Bean
    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public DriverManagerDataSource driverManagerDataSource(DataSourcePropertiesMap dbPropsMap) {
        var ds = new DriverManagerDataSource(dbPropsMap.getDbURL(), dbPropsMap.getDbUsername(), dbPropsMap.getDbPassword());
        ds.setDriverClassName(dbPropsMap.getDbDriver());
        return ds;
    }
}

DataSourcePropertiesMap 只是四个参数的容器,如下所示:

@Getter
@AllArgsConstructor
public class DataSourcePropertiesMap {

    @NonNull private final String dbURL;
    @NonNull private final String dbUsername;
    @NonNull private final String dbPassword;
    @NonNull private final String dbDriver;
}

每当我启动应用程序时,它都会抛出以下异常:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'healthContributorRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Unsatisfied dependency expressed through method 'healthContributorRegistry' parameter 2; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dbHealthContributor' defined in class path resource [org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.class]: Unsatisfied dependency expressed through method 'dbHealthContributor' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'driverManagerDataSource' defined in class path resource [Cfg.class]: Unsatisfied dependency expressed through method 'driverManagerDataSource' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'DataSourcePropertiesMap' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

为什么 Spring 仍然需要 DriverManagerDataSource 的参数以及 Prototyped Scoped bean 的有效驱动程序类。我的假设是它会以某种方式注册一个 bean 并在使用参数进行调用时创建一个新实例。如果我使用虚拟值创建 DataSourcePropertiesMap 类型的默认 bean,则它需要一个有效的驱动程序类。

【问题讨论】:

  • 您可以使用带有命名 driverManagerDataSource 的 @Qualifier 注释,并使用该名称调用该 bean。
  • 这是关于自动装配 DataSourcePropertiesMap 类型的 bean。但如果我必须在启动时提供所有细节,那么我认为它违背了原型范围的目的

标签: spring spring-boot


【解决方案1】:

编辑我的原始答案,因为我还没有看到问题的这一部分

url、用户名、密码、驱动程序的详细信息将在 运行。

从 spring boot 2.x 开始,仍然没有在运行时自动加载属性的方法。您将不得不手动解析文件并读取此原型 bean 方法中的那些属性。

【讨论】:

  • 这就是我想要做的。应用程序将在运行时加载不同的属性并解析值并创建 DataSourcePropertiesMap 的实例,Function&lt;DataSourcePropertiesMap, DriverManagerDataSource&gt; 将提供一个新实例。但是为什么我必须在配置中@AutowireDataSourcePropertiesMap的一个默认实例才能启动应用程序?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
  • 2015-04-19
相关资源
最近更新 更多