Spring 使用计算机名而不是提供的用户名进行 jdbc 数据库访问

Spring use Computer name instead of supplied username for jdbc database access

Reading Pro Spring 5,显示Spring JDBC正在使用MySQL DB的示例。我用的是书源码。这是代码

@Configuration
@PropertySource("classpath:db/jdbc2.properties")
@ComponentScan(basePackages = "com.apress.prospring5.ch6")
public class AppConfig {

    private static Logger logger = LoggerFactory.getLogger(AppConfig.class);
    @Value("${driverClassName}")
    private String driverClassName;
    @Value("${url}")
    private String url;
    @Value("${username}")
    private String username;
    @Value("${password}")
    private String password;

@Bean(destroyMethod = "close")
    public DataSource dataSource() {
        try {
            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName(driverClassName);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            return dataSource;
        } catch (Exception e) {
            logger.error("DBCP DataSource bean cannot be created!", e);
            return null;
        }
    }

jdbc2.properties

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/musicdb?useSSL=true
username=prospring5
password=prospring5

测试

public class AnnotationJdbcTest {

    private GenericApplicationContext ctx;
    private SingerDao singerDao;

    @Before
    public void setUp() {
        ctx = new AnnotationConfigApplicationContext(AppConfig.class);
        singerDao = ctx.getBean(SingerDao.class);
        assertNotNull(singerDao);
    }

    @Test
    public void testFindAll() {
        List<Singer> singers = singerDao.findAll();
        assertTrue(singers.size() == 3);
        listSingers(singers);
        ctx.close();
    }

我的 MySQL 实例已经有用户 prospring5 以及创建和填充的模式

当我尝试 运行 AnnotationJdbcTest 时,出现此异常:

Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (Access denied for user 'Mehdi'@'localhost' (using password: YES))
org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (Access denied for user 'Mehdi'@'localhost' (using password: YES))
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:82)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:612)

如您所见,该项目正在使用我的计算机名称 'Mehdi' 而不是 .properties 文件中的名称 'prospring5' 。这是为什么?我该如何解决?

您可以从这里自己下载源代码 运行:https://github.com/Apress/pro-spring-5 该项目是:chapter6/spring-jdbc-annotations

编辑: 我按照@STaefi 的建议打印了值,这里是输出:

com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/musicdb?useSSL=false
Mehdi
prospring5

代码

@Bean()
    public DataSource dataSource() {
        try {
            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName(driverClassName);
            System.out.println(driverClassName);
            dataSource.setUrl(url);
            System.out.println(url);
            dataSource.setUsername(username);
            System.out.println(username);
            dataSource.setPassword(password);
            System.out.println(password);
            return dataSource;

首先,我尝试在初始化时设置值,但这并不好。但是在我使用 username = "prospring5"; dataSource.setUsername(username); 之后它起作用了。那么这是什么意思。为什么 Spring 无法像成功加载 url 和密码那样加载用户名。

您能否尝试提供一个默认值:

@Value("${driverClassName:com.mysql.cj.jdbc.Driver}")
private String driverClassName;
@Value("${url:jdbc:mysql://localhost:3306/musicdb?useSSL=true}")
private String url;
@Value("${username:prospring5}")
private String username;
@Value("${password:prospring5}")
private String password;

并删除顶部的@PropertySource("classpath:db/jdbc2.properties")。如果这有效,那么您可以再次尝试使用 propertySource

所以我通过简单地在 .propreties 文件中使用不同的字符串标识符解决了这个问题。我将其更改为 one=prospring5 并且有效。显然,使用名为 'username' 的属性将加载除您的计算机名称以外的任何内容。我不知道 Spring 是否提供了 属性 名称的禁止值列表。如果他们不这样做,他们当然应该考虑。