记录下关于ConfigurationProperties在方法上获取数据源为null的这个坑吧

博客记录了同事提出的ConfigurationProperties注入问题。起初取值datasource为null,原因是config未注入,用RestController请求并注入Service后可取值。尝试实体bean注入方式提前获取未成功,启动时为null,请求时才获配置结果,推算该属性是lazy性质。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说起这件事还是有点小插曲,一个刚来不久的同事问起了这个问题,看了下没问题啊,是不是注入方式不对呢?或者configuration根本就没有注入进来?当场没有解决,这个耿直BOY竟然说我水,哎老脸往哪搁。记录下:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;

import javax.sql.DataSource;

@Configuration
public class MyConfigFactory {
    // 该方式在ConfigurationProperties注解在类上可直接获取,因此可定义一个属性类做映射来获取配置文件。这种取值方式是可以取到的,而ConfigurationProperties注解在如下方法的DataSource=null
    @Value("${spring.datasource.username}")
    private String username;

    public String getUsername() {
        return username;
    }

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource", ignoreInvalidFields = true)
    public DataSource getDataSource(){
        DataSource dataSource = DataSourceBuilder.create().build();
        return dataSource;
    }
}

确实该处取值的datasource=null,原因是config还没有注入进来,但是我用RestController请求之后,使用Autowried注入Service后即可取到了。

==================Service方法=========================
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;

@Service
public class MyDataSourceService {
    @Autowired
    MyConfigFactory myConfigFactory;

    public void getDataSource(){
        DataSource dataSource = myConfigFactory.getDataSource();
        System.out.println(dataSource);
    }
}

==================Controller方法=========================
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @Autowired
    private MyDataSourceService myDataSource;

    @RequestMapping(value = "/info", method = RequestMethod.GET)
    public String getInfo(){
        myDataSource.getDataSource();
        return  "AAAAA";
    }
}

接口请求后,发现DataSource可获得数据源了。我想这种类似于事务补偿机制吧?后续填值得方式。而后我使用实体bean得注入方式尝试看看是否能提前获取到呢?

结果呢!并没有奇迹,启动时查看还是为null,而后请求时才获得配置文件得结果。因此可推算该属性是lazy性质。使用之前得好好考虑是否可容许这种方式。

具体的ConfigurationProperties注入方式等后续研究到该部分再详细说明吧。

 

 

 

### MyBatis Plus 中使用 `@DS` 注解实现动态数据源 #### 动态数据源的概念与作用 在分布式系统或多租户架构下,应用可能需要连接多个不同的数据库实例来获取或存储数据。为了简化这种操作并提高灵活性,可以采用动态数据源技术,在运行时根据业务逻辑自动切换到指定的数据源。 #### 配置多数据源支持 要在项目中启用对多个数据源的支持,需先定义各个数据源的具体参数,并通过Spring Boot的配置类将其注册至容器内: ```java @Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @Primary @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.master") public DataSource primaryDataSource() { return new HikariDataSource(); } @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.slave") public DataSource secondaryDataSource() { return new HikariDataSource(); } } ``` 上述代码片段展示了如何创建两个名为 `primaryDataSource` 和 `secondaryDataSource` 的数据源bean对象[^3]。 #### 启用 AOP 切面拦截器 为了让 `@DS` 注解生效,还需引入AOP切面编程机制,以便能够在方法调用前改变当前线程绑定的目标数据源名称。这通常由框架自带组件完成,开发者只需确保依赖项已加入pom.xml文件即可。 #### 应用层面上的应用方式 当一切准备就绪之后,便可以在Service层的方法上标注 `@DS("dataSourceName")` 来指示具体要使用的数据源名: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override @DS("slave") public List<User> getAllUsersFromSlaveDB(){ return userMapper.selectList(null); } @Override @DS("master") public void saveUserToMasterDB(User user){ userMapper.insert(user); } } ``` 这里分别指定了查询用户列表时应访问从库(`slave`)以及新增用户记录时则指向主库(`master`)的操作模式[^1]。 需要注意的是,如果在同一事务上下文中同时存在针对不同数据源的操作,则可能导致部分情况下 `@DS` 标签失去效果。此时建议调整设计思路或将涉及跨库变更的部分拆分为独立的服务接口处理[^2]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值