如何在抽象类中获取ApplicationContext引用?
解决方案
问题根源
你遇到的空指针问题,核心是Spring Bean的初始化顺序:构造函数会先执行,此时Spring还未完成ApplicationContext的注入(无论是@Autowired的setter还是ApplicationContextAware的回调,都在构造函数执行之后),所以在构造函数里调用setConfigClass时,applicationContext还未赋值。
方案一:用@PostConstruct延迟初始化逻辑
@PostConstruct标注的方法会在Bean构造完成、所有依赖注入完成后执行,此时ApplicationContext已经可用。
修改FirstCheck类:
@Component @DependsOn({"myConfig"}) public class FirstCheck extends BaseCheck { @PostConstruct public void init() { setConfigClass("myConfig"); } }
你的BaseCheck类无需改动,保持原有的@Autowired注入ApplicationContext即可。
方案二:抽象类实现ApplicationContextAware配合初始化方法
抽象类实现ApplicationContextAware是完全可行的,问题出在你过早调用了依赖ApplicationContext的方法。只需将初始化逻辑移到@PostConstruct中:
先修改BaseCheck实现接口:
public abstract class BaseCheck implements ApplicationContextAware { private ApplicationContext applicationContext; protected AbstractConfig configClass; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public AbstractConfig getConfigClass() { return configClass; } public void setConfigClass(String configClass) { this.configClass = (AbstractConfig) applicationContext.getBean(configClass); } }
然后给FirstCheck添加@PostConstruct初始化方法,和方案一的修改一致。
方案三:直接依赖注入AbstractConfig(推荐)
既然已经用@DependsOn确保myConfig提前初始化,不如直接通过Spring的依赖注入获取Bean,完全避免手动从ApplicationContext拿取的操作,更符合Spring的设计理念:
修改BaseCheck
public abstract class BaseCheck { protected AbstractConfig configClass; public AbstractConfig getConfigClass() { return configClass; } public void setConfigClass(AbstractConfig configClass) { this.configClass = configClass; } }
修改FirstCheck(构造注入方式)
@Component @DependsOn({"myConfig"}) public class FirstCheck extends BaseCheck { @Autowired public FirstCheck(@Qualifier("myConfig") AbstractConfig config) { setConfigClass(config); } }
或用setter注入方式
@Component @DependsOn({"myConfig"}) public class FirstCheck extends BaseCheck { @Autowired @Qualifier("myConfig") @Override public void setConfigClass(AbstractConfig configClass) { super.setConfigClass(configClass); } }
内容的提问来源于stack exchange,提问作者boardtc
相关产品推荐
相关产品推荐

