说当Spring上下文层次结构关闭时,没有保证豆子将被销毁的顺序是正确的吗?例如,子上下文中的豆子将在父上下文中销毁。从一个最小的例子来看,上下文的破坏似乎在上下文之间是完全不协调的(奇怪的是)。这两个上下文都注册一个 shutdown hook,稍后将在不同的线程中执行。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextHierarchy({
@ContextConfiguration(classes = {ATest.Root.class}),
@ContextConfiguration(classes = {ATest.Child.class})
})
public class ATest {
@Test
public void contextTest() {
}
public static class Root {
@Bean
Foo foo() {
return new Foo();
}
}
public static class Child {
@Bean
Bar bar() {
return new Bar();
}
}
static class Foo {
Logger logger = LoggerFactory.getLogger(Foo.class);
volatile boolean destroyed;
@PostConstruct
void setup() {
logger.info("foo setup");
}
@PreDestroy
void destroy() {
destroyed = true;
logger.info("foo destroy");
}
}
static class Bar {
@Autowired
Foo foo;
Logger logger = LoggerFactory.getLogger(Bar.class);
@PostConstruct
void setup() {
logger.info("bar setup with foo = {}", foo);
}
@PreDestroy
void destroy() {
logger.info("bar destroy, foo is destroyed={}", foo.destroyed);
}
}
}
给出输出:
21:38:53.287 [Test worker] INFO ATest$Foo - foo setup
21:38:53.327 [Test worker] INFO ATest$Bar - bar setup with foo = com.tango.citrine.spring.ATest$Foo@2458117b
21:38:53.363 [Thread-4] INFO ATest$Foo - foo destroy
21:38:53.364 [Thread-5] INFO ATest$Bar - bar destroy, foo is destroyed=true
有没有办法强制以“正确”的顺序关闭上下文?
我自己也挖掘了同样的问题,一切看起来都不再奇怪了。虽然我仍然希望这表现不同。
当你有父母时
现在可能有一些区别
这种情况最常见的设置(不包括单上下文设置)是通过 DispatcherServlet
使用 ContextLoaderListener
和子上下文声明根上下文。
当webapp(或容器)关闭时,ContextLoaderListener
和DispatcherServlet
,通过ServletContextListener.contextDestroyed(…)
和Servlet接收通知。destroy()
相应地。
根据javadoc首先servlet
因此,在servlet容器中运行的webapp中,首先销毁DispatcherServlet
上下文(它是子1),然后才销毁根上下文。
以下内容不仅适用于独立的WEApp,也适用于使用分层上下文的任何独立的Spring应用。
由于没有容器,因此 stanadlone 应用程序需要与 JVM 本身通信,以便接收关闭信号并对其进行处理。这是使用关机钩子机制完成的。
除了JVM capabilities\version之外,Spring并不试图推断它运行的环境(但是Spring Boot在自动推断env方面做得很好)。
因此,要使Spring注册一个关闭挂钩,您需要在创建上下文(javadoc)时说它这样做。如果您不这样做,您将根本无法调用@PreDestroy
/DisposableBean
回调。
一旦您向JVM注册了上下文的关机挂钩,它将收到通知,并将正确处理该上下文的关机。
如果您有父子上下文,您可能希望< code >。registerShutdownHook()。这在某些情况下是可行的。但是JVM以不确定的顺序调用关闭挂钩,所以不幸的是,这并没有真正解决主题问题。
那我们该怎么办呢
可能最简单的(尽管不是最优雅的)解决方案是拥有一个< code>ApplicationListener
@Autowire
或@DependsOn
或xml对应项)最初的问题提出了一个JUnit测试。我真的没有挖那么远,但我怀疑这个又是不同的。因为是SpringJUnit4ClassRunner
统治着它们,首先是上下文层次结构。另一方面,JUnit测试有一个定义良好和管理的生命周期(几乎列出servlet容器)。
任何方式已经了解内部工作,我相信它应该很容易为你解决这个:)
我在web中配置了spring根web上下文。xml文件。我也有几个与此父项相关的子上下文。所有子上下文都是手动创建的: 我想在这个子上下文中管理会话和请求范围的bean。 如何正确创建和配置子上下文,使其能够处理web应用程序范围? 现在我在尝试自动装配会话范围的bean时出现以下错误(显然):
问题内容: 像这样对表格进行排序的最佳方法是什么: 要通过分级排序,它 的ID 或 名字 : “比萨饼” //节点1 “piperoni” //节点1.1 “奶酪” //节点1.2 “额外的奶酪” //节点1.2.1 “vegetariana” //节点1.3 “汉堡” //节点2 ‘咖啡’//节点3 编辑: 名称 末尾的数字是为了更好地可视化strucutre,而不是用于排序。 编辑2: 正如多
我是Spring的新手,如果我做了一些愚蠢的事情,请原谅我。我正在尝试为我的应用程序编写一个使用Spring的集成测试。 我正在创建一个上下文层次结构,如下所示 在我的测试方法中,我试图创建一个新的子上下文,它只有一个bean,它是一个应用程序侦听器,依赖于父方法中的bean。 我面临的问题是,来自子上下文的bean没有收到应用程序事件的通知,而且@Value注释也没有得到处理。 我到底做错了什么
到目前为止,我们一直在使用Spring JpaRepository来满足我们的需求。我觉得这个新需求需要自定义查询,我不认为可以直接使用JParepository来处理这个问题。我只想知道你是怎么想的。不需要自定义sql查询就可以做到这一点吗?
问题内容: 考虑下面的代码 基于我对类成员初始化和构造函数执行顺序的理解。我期望输出是 因为我相信类成员甚至在调用main方法之前就已初始化。但是当我运行程序时,我得到以下输出 我的困惑是,尽管Meal()Lunch()和PortableLunch()在Bread()Cheese()和Lettuce()之前运行,即使它们的构造函数被调用。 问题答案: 这些是实例字段 它们仅在创建实例时存在(执行)
我有这样的层次结构: 因此,用户可以添加他的工作经验。此外,他还可以为特定的项目添加角色。 我想为用户id 1获取项目,但项目之间只有关系 获取用户 获得工作经验 获取角色 获取项目 因此,如果我有更多不同工作经验的角色,我就必须提出20个请求才能得到我的项目。这不是很有效率吗?我必须加载一些不必要的数据。。。 是否可以只创建endpoint:并按用户ID过滤它? 应该如何在API上管理它?对我来