为啥 Spring 忽略了我的 @DependsOn 注释?
Posted
技术标签:
【中文标题】为啥 Spring 忽略了我的 @DependsOn 注释?【英文标题】:Why did Spring ignore my @DependsOn annotation?为什么 Spring 忽略了我的 @DependsOn 注释? 【发布时间】:2014-04-06 09:19:16 【问题描述】:我将 Spring 3.1.3 用于 web 应用程序,使用 XML 配置和组件扫描。
我意识到必须先对扫描的组件之一进行初始化。在所有需要构造后初始化的类上,我在方法上都有一个 @PostConstruct 注释。
为了设置依赖顺序,我将需要在其他类之前构建的类上的“@Component”更改为“@Component("configData")”。然后,我在每个需要在“configData”bean 之后构建的类定义之前添加了 '@DependsOn("configData")'。
根据我的阅读,这就是我强制执行依赖顺序所需的全部内容。
然后我构建了所有内容,设置了断点,并启动了应用程序。我希望在任何依赖 bean 之前命中“configData”bean 中的断点。这不是发生的事情。第一个断点位于其中一个依赖 bean 的“init”方法中。
然后我更改了我的“log4j.xml”以将“调试”设置为“org.springframework”的日志记录级别并重新运行我的测试。断点行为是一样的,我的日志没有显示任何关于 Spring 初始化的调试信息(我已经调试了 log4j 初始化本身,所以我确认我已经为“org.springframework”设置了调试)。
我可能缺少什么?
更新:
如果重要的话,这里有几个我在这里所做的基本示例。
@Component("configData")
public class ConfigData
....
@PostConstruct
public void init()
....
@Component
@DependsOn("configData")
public class ClassDependentOnConfigData extends BaseClass
....
@Override
@PostConstruct
public void init()
super.init();
....
重申一下,我在运行时发现的是 Spring 在“ConfigData”中的“init()”方法之前调用了“ClassDependentOnConfigData”中的“init()”方法。
还要注意,“BaseClass”对于“ConfigData”有一个“@Autowired”。
【问题讨论】:
你能发布configData bean的bean定义(Java和/或XML),以及一个应该在它之后初始化的bean作为例子吗? 好的,但这些只是骷髅,从我的描述中你会看到的很明显。 至于看不到 Spring 调试消息。您是否检查过您没有全局 THRESHOLD 集或 appender 集?换句话说 - 您是否看到其他 DEBUG 消息? 顺便说一句 - 如果您隔离一个显示问题的工作示例,它将对每个人(实际上是您自己)有很大帮助。我知道您进行了一些复制和粘贴,但我们没有看到所有内容,也无法自行运行。 承认工作示例评论。我现在有一个解决方法,但我仍然想解决这个问题。关于日志消息,这令人困惑。我已将根记录器设置为调试,它在我的控制台日志中显示了这一点,但我仍然没有看到任何 DEBUG 消息。 【参考方案1】:(来自其他人的正确但现已删除的答案)
@DependsOn 合约只保证 bean 已经构建并且属性已经设置。这不能保证任何 @PostConstruct 方法都已被调用。
实现这一点的方法是让“dependee”类(其他人依赖的类)实现“InitializingBean”类,这需要实现“afterPropertiesSet()”方法。我将“init()”方法的原始主体放入此方法中。我验证了它现在在任何依赖它的类之前执行。
原始答案中提到的另一件事是,如果我在 XML 中定义了我的“依赖”bean 并使用了“init-method”属性,那么它会在任何依赖它的类之前执行。我没有验证这一点。
【讨论】:
感谢您再次添加答案,我这两天一直在寻找这个解决方案!【参考方案2】:我也遇到了同样的问题,但仍然没有正确解决。作为解决方案的一部分,Spring 文档说:
“除非使用组件扫描,否则在类级别使用 DependsOn 无效。”
这就是@dependsOn注解不起作用的原因。
【讨论】:
但是还有哪些其他级别?以上是关于为啥 Spring 忽略了我的 @DependsOn 注释?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 MySQL WorkBench 在使用游标时忽略了我的 SIGNAL SQLSTATE?
为啥 Rails 脚手架生成器只是忽略了我的 config/initializers/inflections.rb?
为什么Spring Boot的资源优先级忽略了我的外部属性文件?
为啥 spring-cloud-starter-config 忽略 bootstrap.properties?