提问人:mattsmith5 提问时间:11/8/2023 最后编辑:mattsmith5 更新时间:11/17/2023 访问量:273
Java 创建 JDBCTemplate Singleton Bean 而不编写 DataSource
Java Create JDBCTemplate Singleton Bean without Writing DataSource
问:
我正在尝试使JdbcTemplate成为Singleton Bean,而不是在多个存储库中调用它。
在当前的代码库中,我甚至不需要编写 DataSource 配置。
对于我的新代码单例配置 Bean 尝试,有没有办法在不经过 DataSource 配置的情况下设置 JDBCTemplate?
当前代码:
@Repository
public class CustomerRepositoryImpl implements CustomerRepository {
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Autowired
public CustomerRepositoryImpl(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
}
它将使用 application.properties 文件自动读取 DataSource
spring.datasource.url= jdbc:sqlserver://localhost;encrypt=true;databaseName=Test
spring.datasource.username= sauser
spring.datasource.password= sauserpw
新代码尝试:
@Configuration
public class DatabaseConfig {
@Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource)
{
return new NamedParameterJdbcTemplate(dataSource);
}
}
// trying to prevent writing this code in for Datasource if possible, and importing a new maven package com.microsoft.sqlserver.jdbc.SQLServerDataSource;
SQLServerDataSource dataSource = new SQLServerDataSource();
dataSource.setUser("sauser");
dataSource.setPassword("sauserpw");
dataSource.setServerName("localhost");
dataSource.setDatabaseName("Test");
@Repository
public class CustomerRepositoryImpl implements CustomerRepository {
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Autowired
public CustomerRepositoryImpl(DatabaseConfig databaseConfig) {
this.namedParameterJdbcTemplate = databaseConfig.namedParameterJdbcTemplate();
注意:没有错误,试图减少代码库并简化它
答:
你为什么要创建?我手头没有源代码,但您当前的代码正在工作,您注入了一个 jdbc-Template,它是通过 autocobfiguration 创建的(作为单例)。DatabaseConfig
自动配置的实现方式是,当满足某些条件时,它会退缩,以免干扰手动配置。
很有可能,通过自己创建 jdbctemplate,数据源配置会退缩。
您可以通过在调试模式下启动 spring boot 来检查这一点。您可以在那里看到选择了哪些自动配置,省略了哪些自动配置以及原因。
如果你仍然想创建自己的jdbctemplate,你可以像Spring Boot一样创建数据源。在这种情况下,我看了一下相应的Spring Boot源代码。例如,数据库属性被加载到 bean 中......DatabaseProperties
顺便说一句。您的新存储库代码是不必要的,复杂的。如果你有一个 Configuration 类,它创建一个 bean,那么它默认是一个单例。如果你自动连接该 bean,你就会注入单例。注入配置类并调用 Bean 方法会使它变得不必要复杂。我建议您使用调试器并在执行期间检查对象 ID,以了解其工作原理。
尝试将具有自动连线数据源配置的包导入到Spring 中。这样您就可以在上面的注释Auotwired 中使用spring-boot-autoconfigure
JdbcTemplate
你可以直接使用 JdbcTemplate 并将其作为 bean 注入,spring 会自动处理一切。由于在您的情况下,您只需要连接单个数据源,提及必需的依赖关系和相关属性,因此将 JdbcTemplate 声明为 bean 将解决您的所有问题。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class JdbcTemplateConfig {
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
这将是你的 JdbcConfig。 注意:你不需要 JdbcConfig 类,你可以直接在应用程序的配置中初始化 JdbcTemplate bean。
在项目中包含依赖项。spring-boot-starter-data-jpa
您可以通过以下方式在存储库中使用此 Bean。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class YourRepository {
private final JdbcTemplate jdbcTemplate;
@Autowired
public YourRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public String fetchData() {
String sql = "SELECT your_column FROM your_table WHERE some_condition";
return jdbcTemplate.queryForObject(sql, String.class);
}
}
希望这能解决您的问题。
当然,你可以启用自动配置,但这并不能改变一个事实,即你必须以某种方式让 Spring 知道数据库参数。严格来说,您已经使用过它,因为在 Java 代码中指出 中没有显式赋值的值正是 Autoconfiguration 的一个例子。application.properties
鉴于此,问题究竟是什么目标?要摆脱项目中的配置?如果是这样,我建议你看一下Spring Cloud Configuration,它提供了许多项目外的配置方式,如git、vault、DB等。 另一种方法是在配置文件中省略数据库配置参数,并将它们作为环境变量传递。问题是,每个配置参数都可以被描述为一个环境变量,遵循一个简单的命名约定:句点分隔的配置参数将被同名的环境变量覆盖。句点变为下划线,破折号将被省略。
server.port -> SERVER_PORT
my.new-param -> MY_NEWPARAM
Spring 参考中有关于配置外部化的部分。如果混合使用,请记住 java/env/file 配置的优先级。
再说一遍:这不是魔术,你不能只是删除数据源的配置——它是一种抽象,让你的服务知道如何连接到数据库。但是,您可以将此配置与项目分开保存和管理。
评论
spring-boot-autoconfigure
Auotwired