Java 为什么 Spring 忽略了我的 @DependsOn 注释?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22178735/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:07:14  来源:igfitidea点击:

Why did Spring ignore my @DependsOn annotation?

javaspring

提问by David M. Karr

I'm using Spring 3.1.3 for a webapp, using XML configuration with component scanning.

我将 Spring 3.1.3 用于 webapp,使用 XML 配置和组件扫描。

I realized that one of the scanned components has to be initialized before several others. On all the classes that need post-construct initialization, I have a @PostConstruct annotation on a method.

我意识到扫描的组件之一必须在其他几个组件之前初始化。在所有需要构造后初始化的类上,我在一个方法上有一个 @PostConstruct 注释。

To set up the dependency order, I changed '@Component' to '@Component("configData")' on the class that needs to be post-constructed before the others. I then added '@DependsOn("configData")' just before each class definition that needs to be post-constructed AFTER the "configData" bean.

为了设置依赖顺序,我将需要在其他类之前构建的类上的 '@Component' 更改为 '@Component("configData")'。然后我在每个需要在“configData”bean 之后构建的类定义之前添加了 '@DependsOn("configData")'。

From what I've read, this is all I need to enforce the dependency order.

从我读到的内容来看,这就是我强制执行依赖顺序所需的全部内容。

I then built everything, set my breakpoints, and started up the app. I expected to hit the breakpoint in the "configData" bean before any of the dependent beans. This isn't what happened. The first breakpoint was in the "init" method of one of the dependent beans.

然后我构建了所有东西,设置了我的断点,并启动了应用程序。我希望在任何依赖 bean 之前到达“configData” bean 中的断点。这不是发生的事情。第一个断点位于一个依赖 bean 的“init”方法中。

I then changed my "log4j.xml" to set "debug" as the logging level for "org.springframework" and reran my test. The breakpoint behavior was the same, and my logging didn't show any debug information about Spring initialization (I have debugging on for log4j initialization itself, so I confirmed that I had DEBUG set for "org.springframework").

然后我更改了我的“log4j.xml”以将“debug”设置为“org.springframework”的日志记录级别并重新运行我的测试。断点行为是一样的,我的日志没有显示任何关于 Spring 初始化的调试信息(我对 log4j 初始化本身进行了调试,所以我确认我为“org.springframework”设置了 DEBUG)。

What might I be missing?

我可能缺少什么?

Update:

更新:

If it matters, here are a couple of skeleton examples of what I'm doing here.

如果重要的话,这里有几个我在这里所做的事情的骨架示例。

@Component("configData")
public class ConfigData {
    ....
    @PostConstruct
    public void init() {
        ....
    }
}

@Component
@DependsOn("configData")
public class ClassDependentOnConfigData extends BaseClass {
    ....
    @Override
    @PostConstruct
    public void init() {
        super.init();
        ....
    }
}

To reiterate, what I'm finding at runtime is that the "init()" method in "ClassDependentOnConfigData" is being called by Spring before the "init()" method in "ConfigData".

重申一下,我在运行时发现“ClassDependentOnConfigData”中的“init()”方法在“ConfigData”中的“init()”方法之前被Spring调用。

Note also that "BaseClass" has an "@Autowired" for "ConfigData".

另请注意,“BaseClass”具有“ConfigData”的“@Autowired”。

采纳答案by David M. Karr

(From someone else's correct but now deleted answer)

(来自其他人的正确但现在已删除的答案)

The @DependsOn contract only guarantees that the bean has been constructed and properties have been set. This will not guarantee that any @PostConstruct methods have been called.

@DependsOn 合约仅保证 bean 已被构造并已设置属性。这不能保证已调用任何 @PostConstruct 方法。

The way to get this to work is to have the "dependee" class (the class that others depend on) implement the "InitializingBean" class, which requires implementing the "afterPropertiesSet()" method. I put the original body of my "init()" method into this method. I verified that this is now executed before any of the classes that depend on this.

让它工作的方法是让“dependee”类(其他人依赖的类)实现“InitializingBean”类,这需要实现“afterPropertiesSet()”方法。我将“init()”方法的原始主体放入此方法中。我验证了它现在在任何依赖于此的类之前执行。

Another thing that was mentioned in the original answer is that if I had defined my "dependee" bean in XML and used the "init-method" property, this WOULD have executed before any of the classes that depend on this. I didn't verify this.

原始答案中提到的另一件事是,如果我在 XML 中定义了我的“dependee”bean 并使用了“init-method”属性,那么这将在任何依赖于此的类之前执行。我没有验证这一点。

回答by FredEtHop

I also encoutered the same problem, but still not properly resolved. As a part of a solution Spring documentation says:

我也遇到了同样的问题,但仍然没有正确解决。作为解决方案的一部分,Spring 文档说:

"Using DependsOn at the class level has no effect unless component-scanning is being used."

“除非正在使用组件扫描,否则在类级别使用 DependsOn 无效。”

This is the reason why the @dependsOn annotation has no effect.

这就是@dependsOn 注释不起作用的原因。