设置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 楼答案
所有依赖项都应该在调用任何
@Bean
方法之前被注入,所以这很奇怪如果这不起作用,那么你在其他地方做了一些非常奇怪的事情: