有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

设置autowire后运行java数据源bean

我试图在dataSource bean初始化中获取应用程序属性,但我发现此时还没有设置Autowire,所以那些带有@Autowire的变量仍然为null。例如:

@Configuration
@EnableTransactionManagement
public class Config{

    @Autowired
    private Environment environment;

    @Bean
    public DataSource dataSource() {
        DataSourceBuilder builder = DataSourceBuilder.create();
   
        builder.driverClassName("org.h2.Driver");
        builder.url("jdbc:h2:mem:test");
        builder.username("someUser");
        builder.password("somePass");
    
        return builder.build();
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        //...
        return emf.getObject();
    }
}

此时,如果我尝试使用环境,它仍然为空。我对此进行了深入研究,找到了一些可能的解决方案,扩展了环境感知和其他一些东西,但在数据源之前,它们似乎都没有成功。在环境感知中,它在传递数据源bean后调用集合

我正在研究类SpringApplication,一切似乎都发生在配置应用程序上下文运行(字符串…args),在刷新上下文(上下文)中,它调用数据源bean作为Autowire初始化的一部分

进一步挖掘,我发现在初始化过程中会发生一些事件,可以在spring中手动钩住它们。工厂,指向你想做某事的类

我用它做了一个测试,你可以访问应用程序环境变量

public class EnvironmentProcessor implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {           
        final var propertySources = environment.getPropertySources();
        PropertySource<?> property = new MapPropertySource("customProperty",
                Collections.<String, Object>singletonMap("test.value", "worked as intended"));
        propertySources.addLast(property);
    }

}

看起来不错,但是我试着用Autowire来获取环境。属性返回,但它仍然为空

@Value("${test.value}")
private String test;

如果我让代码运行,在EntityManagerFactory EntityManagerFactory()中,它确实完成了所有的Autowire,所以测试。价值是存在的,环境也是存在的,但现在已经太晚了

在我看来,我错过了一些东西,一个设置顺序的配置,或者我把其他东西搞砸了

假设事情是这样的,这是bean初始化的顺序,那么在这种情况下,我如何利用spring呢。在调用数据源bean时,我可以访问这些变量吗

为了能够读取这些属性,我要做的是手动加载应用程序。具有

    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    Properties appProp = new Properties();
    try ( InputStream resourceStream = loader.getResourceAsStream("application.properties")) {
        appProp.load(resourceStream);
    }

这是可行的,但似乎是错误的

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    所有依赖项都应该在调用任何@Bean方法之前被注入,所以这很奇怪

    如果这不起作用,那么你在其他地方做了一些非常奇怪的事情:

    @Bean
    public DataSource dataSource(Environment env) {
       // ...
    }