java - 设置自动装配后运行 dataSource bean
问题描述
我试图在 dataSource bean 初始化中获取应用程序属性,但我发现此时尚未设置 Autowire,因此具有 @Autowire 的那些变量仍然为空。例如:
@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();
}
}
此时如果我尝试使用Environment 环境,它仍然为空。我正在研究它,发现一些可能的解决方案扩展了EnvironmentAware和其他一些东西,但它们似乎都没有在dataSource之前出现。在EnvironmentAware中,它在传递dataSource bean后调用集合。
我正在研究SpringApplication 类,一切似乎都发生在ConfigurableApplicationContext run(String... args)中,在refreshContext(context)中,它调用dataSource bean 作为 Autowire 初始化的一部分。
再深入一点,我发现你有一些在初始化期间发生的事件,你可以在spring.factories中手动挂钩,指向你想要做某事的类。
我确实用它做了一个测试,你确实可以访问应用程序和环境变量
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 来获取 env.property 并且它仍然为空。
@Value("${test.value}")
private String test;
如果我让代码运行,在EntityManagerFactory entityManagerFactory()中,它确实完成了所有 Autowire,所以test.value和Environment environment都在那里,但那时已经为时已晚。
在我看来,我在这里遗漏了一些东西,设置订单的配置,或者我搞砸了其他东西。
假设事情就是这样,这是初始化 bean 的顺序,所以在这种情况下,我怎样才能以某种方式使用 spring.factories,以便在dataSource时可以访问这些变量豆叫什么?
为了能够读取这些属性,我正在做的是手动加载 application.properties
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Properties appProp = new Properties();
try ( InputStream resourceStream = loader.getResourceAsStream("application.properties")) {
appProp.load(resourceStream);
}
它有效,但似乎是错误的。
提前致谢。
解决方案
应该在@Bean
调用任何方法之前注入所有依赖项,所以这很奇怪。
如果这不起作用,那么你在其他地方做了一些非常奇怪的事情来导致它:
@Bean
public DataSource dataSource(Environment env) {
// ...
}
推荐阅读
- javascript - 提交后仍会重定向 AJAX 调用的联系表单
- unity3d - 如何从 Animator 中检索当前正在播放的动画?
- wordpress - 如何在wordpress插件联系表7中验证当前服务器时间?
- python - 如何使用 matplotlib 绘制 0/1 的数组
- docker - 使用主机网络启动 Docker 容器,同时保持 SSH 进入容器的能力?
- python - 如何使用 cx freeze 使用 setup.py 构建 msi 扩展
- python - 在 Python 中的字典中查找两个值之间的路径
- neo4j - 在 Cypher Neo4j 中找到正确的路径
- mysql - Sql 查询为每个匹配项选择一个结果
- join - 加入第二高值 (Impala)