Spring 子上下文关闭父上下文
Spring Child Context Closes Parent
我有一个使用 child/parent 上下文关系的 Spring 应用程序。这样做的原因是为了确保子上下文从父上下文继承 beans/resources,然后添加更多 beans/resources 以根据需要覆盖它们。但是,当子上下文关闭(退出 try/catch 作用域)时,它开始对它引用的所有 bean 进行清理,包括父作用域中的那些。这是不可取的,因为我需要重用该父上下文来创建另一个子上下文,但它现在是垃圾,因为它包含一堆 disposed/shut-down 个 bean。
问题:
这是子上下文所需的行为吗,因为它应该清理父 bean?如果是,为什么?
我希望子上下文只清理它直接定义的 bean,而不是继承的 bean。这可能吗?
这里是一些相关的代码:
private AbstractApplicationContext createChildContext(Path workspacePath, String catalogPath, boolean force, Map<String, String> buildOptions) {
// Set the properties to pass into the new context
Properties props=new Properties();
props.setProperty("workspacePath", workspacePath.toString());
props.setProperty("databasePath", workspacePath.toString() + File.separator + "data");
props.setProperty("catalog", catalogPath);
props.setProperty("force",String.valueOf(force));
PropertiesPropertySource pps=new PropertiesPropertySource("properties",props);
// Create new context
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext();
context.setParent(applicationContext);
context.getEnvironment().getPropertySources().addFirst(pps);
context.scan(Neo4jConfig.class.getPackage().getName());
context.register(Neo4jConfig.class);
ConfigurableListableBeanFactory beans = context.getBeanFactory();
BuildConfigurationService buildConfiguration = (BuildConfigurationService)beans.createBean(BuildConfigurationService.class);
buildConfiguration.setBuildConfiguration(buildOptions);
beans.registerSingleton("buildConfiguration", buildConfiguration);
context.refresh();
return context;
}
在 Neo4jConfig 中我们这样做...
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableNeo4jRepositories
@EnableTransactionManagement
@EnableSpringConfigured
@EnableCaching(mode=AdviceMode.ASPECTJ)
@Import({ConversionServiceConfiguration.class})
public class Neo4jConfig extends Neo4jConfiguration {
...
@Bean GraphDatabaseService graphDatabaseService(@Value(value = "${databasePath}") String databasePath) {
logger.debug("Creating database using '{}' for the database path.",databasePath);
GraphDatabaseService graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(databasePath);
...
事实证明,问题出在子上下文的 @EnableSpringConfigured
注释上。模糊地描述 here。
当子上下文关闭时,静态 BeanConfigurerSupport
bean 将关闭并且不再可用。但是,因为它是静态的(也被父上下文使用),任何未来的 @Configurable
bean 都无法配置。
如果有人可以评论这是错误还是期望的行为,我会很高兴。
我有一个使用 child/parent 上下文关系的 Spring 应用程序。这样做的原因是为了确保子上下文从父上下文继承 beans/resources,然后添加更多 beans/resources 以根据需要覆盖它们。但是,当子上下文关闭(退出 try/catch 作用域)时,它开始对它引用的所有 bean 进行清理,包括父作用域中的那些。这是不可取的,因为我需要重用该父上下文来创建另一个子上下文,但它现在是垃圾,因为它包含一堆 disposed/shut-down 个 bean。
问题:
这是子上下文所需的行为吗,因为它应该清理父 bean?如果是,为什么?
我希望子上下文只清理它直接定义的 bean,而不是继承的 bean。这可能吗?
这里是一些相关的代码:
private AbstractApplicationContext createChildContext(Path workspacePath, String catalogPath, boolean force, Map<String, String> buildOptions) {
// Set the properties to pass into the new context
Properties props=new Properties();
props.setProperty("workspacePath", workspacePath.toString());
props.setProperty("databasePath", workspacePath.toString() + File.separator + "data");
props.setProperty("catalog", catalogPath);
props.setProperty("force",String.valueOf(force));
PropertiesPropertySource pps=new PropertiesPropertySource("properties",props);
// Create new context
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext();
context.setParent(applicationContext);
context.getEnvironment().getPropertySources().addFirst(pps);
context.scan(Neo4jConfig.class.getPackage().getName());
context.register(Neo4jConfig.class);
ConfigurableListableBeanFactory beans = context.getBeanFactory();
BuildConfigurationService buildConfiguration = (BuildConfigurationService)beans.createBean(BuildConfigurationService.class);
buildConfiguration.setBuildConfiguration(buildOptions);
beans.registerSingleton("buildConfiguration", buildConfiguration);
context.refresh();
return context;
}
在 Neo4jConfig 中我们这样做...
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableNeo4jRepositories
@EnableTransactionManagement
@EnableSpringConfigured
@EnableCaching(mode=AdviceMode.ASPECTJ)
@Import({ConversionServiceConfiguration.class})
public class Neo4jConfig extends Neo4jConfiguration {
...
@Bean GraphDatabaseService graphDatabaseService(@Value(value = "${databasePath}") String databasePath) {
logger.debug("Creating database using '{}' for the database path.",databasePath);
GraphDatabaseService graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(databasePath);
...
事实证明,问题出在子上下文的 @EnableSpringConfigured
注释上。模糊地描述 here。
当子上下文关闭时,静态 BeanConfigurerSupport
bean 将关闭并且不再可用。但是,因为它是静态的(也被父上下文使用),任何未来的 @Configurable
bean 都无法配置。
如果有人可以评论这是错误还是期望的行为,我会很高兴。