提问人:boardtc 提问时间:8/2/2023 最后编辑:boardtc 更新时间:8/2/2023 访问量:71
如何在抽象类中获取applicationContext引用?
How to get an applicationContext reference in abstract class?
问:
我正在重构现有代码,需要在抽象类中获取applicationContext引用。
简化起见,这里有两个类来说明这个问题:
public abstract class BaseCheck {
private ApplicationContext applicationContext;
protected AbstractConfig configClass;
@Autowired
// not called before setConfigClass called so null
public final void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public AbstractConfig getConfigClass() {
return configClass;
}
public void setConfigClass(String configClass) {
// fails due to null applicationContext
this.configClass = (AbstractConfig) applicationContext.getBean(configClass);
}
}
@Component
@DependsOn({"myConfig"})
public class FirstCheck extends BaseCheck {
public FirstCheck() {
setConfigClass("myConfig");
}
}
我无法注入applicationContext。此代码对 setter 进行注释,如 https://www.baeldung.com/spring-autowired-abstract-class
我还尝试实现ApplicationContextAware,但这也不适用于抽象类。
有谁知道我怎样才能让它工作?
答:
1赞
DingHao
8/2/2023
#1
您可以 impl InitializingBean 。
@Component
@DependsOn({"myConfig"})
public class FirstCheck extends BaseCheck implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
setConfigClass("myConfig");
}
}
评论
0赞
boardtc
8/2/2023
不幸的是,我尝试了这个,但没有效果。
1赞
M. Deinum
8/2/2023
#2
问题是您正在尝试访问构造函数中的。此时,该方法尚未被调用,因为 Spring 只能在对象构造后调用它。您在施工期间访问它,因此 .ApplicationContext
setApplicationContext
NullPointerException
您可以做的是将 注入到构造函数中,以便您可以访问它。不要使用 来查找 bean,而是使用 并将正确的配置注入到构造函数中,而不是使用ApplicationContext
ApplicationContext
@Qualifier
setConfigClass
public abstract class BaseCheck {
protected AbstractConfig configClass;
protected BaseCheck(AbstractConfig configClass) {
this.configClass=configClass;
}
public AbstractConfig getConfigClass() {
return configClass;
}
}
@Component
public class FirstCheck extends BaseCheck {
public FirstCheck(@Qualifier("myConfig") AbstractConfig configClass) {
super(configClass);
}
}
这样,您就不需要访问 .无论如何,您已经在构造函数中拥有该名称(现在可以将其删除),因此将其移动到 an 以获得正确的实例应该可以这样做。ApplicationContext
@DependsOn
@Qualifier
评论
0赞
boardtc
8/2/2023
一个令人兴奋的想法!我删除了所有applicationContext引用,并在所有配置上添加了@Qualifier,如图所示。我遇到的一个问题是 FirstCheck,其他问题是侦听器,另一个启动侦听器的类失败,因为配置类为 null。我尝试将@ DependsOn用于侦听器入门类中的所有配置。该代码之前在侦听器启动器构造函数中传递配置的地方工作,但我正在远离它,因为 SonarQube 在构造函数 (9) 中突出显示了太多参数。P.S. 你不能对抽象类进行构造函数注入
0赞
M. Deinum
8/2/2023
只要将引用传递给抽象类(这就是我在这里所做的),就可以毫无问题地进行构造函数注入。使用构造函数注入时,除非您不是通过 Spring 而是在其他地方实例化它们,否则事情就不可能了!null
0赞
boardtc
8/2/2023
我不会挂断电话,baeldung 帖子中有详细介绍。 @EventListener(ApplicationReadyEvent.class) 位于启动侦听器的方法上。配置仍然是空的:-(
1赞
M. Deinum
8/2/2023
现在你把所有这些注释都拉走了......您没有在问题中提及这些内容,因此您的问题包含愚蠢的代码,请提供具有代表性的代码。基本上,依赖项不能为空,应用程序甚至不会以该依赖项启动,并在启动期间因依赖项不满意而爆炸。创建代理,如果事情是私有的,最终的等,这些将对代理隐藏(所以请添加一些实际代码而不是愚蠢的代码)。@EventListener
0赞
boardtc
8/2/2023
谢谢,你已经回答了我提出的问题,对愚蠢的版本是公平的。我使用 Project Lombok 完全删除了构造函数,从而完全消除了这个问题!
下一个:Mongo 模板自定义转换
评论
abstract
不对类进行组件扫描。您必须自动连接扩展子类的构造函数。