You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新增抽象类后@Autowired字段为null,触发NullPointerException

问题描述

原有可正常运行的代码:

@Component
public class MessageUtil {

    @Autowired
    @Qualifier("processMessages")
    private ReloadableConfig config;
    
    public String createMessage() {
        return config.getPropertyStr("message.simple.signature");
    }
}

对应的processMessages Bean定义:

<bean id="processMessages" class="com.company.framework.resources.ReloadableConfig">
    <property name="basename" value="classpath:com/company/aaa/bbb/domain/service/processMessages"/>
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="cacheSeconds" value="60"/>
</bean>

之后创建了新类:

public abstract class MessageBuilder {
    @Autowired
    @Qualifier("processMessages")
    protected ReloadableConfig config;
    
    public abstract String createMessage();
}

@Component
public class SimpleMessageBuilder extends MessageBuilder {
    private String template;

    private void setTemplate() {
        template = config.getPropertyStr("message.simple.signature");
    }

    @Override
    public String createMessage() {
        setTemplate();
        return template;
    }
}

现在调用SimpleMessageBuilder.createMessage()时触发NullPointerException,原因是setTemplate()方法里的config为null,请问这段新代码问题出在哪?

问题分析与修复方案

核心问题

Spring的依赖注入只作用于被容器管理的实例化Bean,而抽象类无法被实例化,所以MessageBuilder里的@Autowired注解根本不会被Spring处理。子类SimpleMessageBuilder继承的config字段自然就是null,调用方法时就会触发空指针。

两种修复方式

方式一:把抽象类纳入Spring容器(不推荐)

给抽象类MessageBuilder加上@Component注解,让Spring管理它,这样抽象类的字段会被注入,子类继承后就能正常使用:

@Component
public abstract class MessageBuilder {
    @Autowired
    @Qualifier("processMessages")
    protected ReloadableConfig config;
    
    public abstract String createMessage();
}

这种方式虽然能解决问题,但抽象类本身不需要被实例化,强行加@Component不符合设计初衷,不推荐。

方式二:在子类中注入依赖(推荐)

直接在子类SimpleMessageBuilder里处理依赖注入,避免依赖抽象类的无效注解。推荐用构造方法注入,这是Spring的最佳实践,能确保实例化时依赖就被初始化:

public abstract class MessageBuilder {
    protected ReloadableConfig config;
    
    public abstract String createMessage();
}

@Component
public class SimpleMessageBuilder extends MessageBuilder {
    private String template;

    @Autowired
    public SimpleMessageBuilder(@Qualifier("processMessages") ReloadableConfig config) {
        this.config = config;
    }

    private void setTemplate() {
        template = config.getPropertyStr("message.simple.signature");
    }

    @Override
    public String createMessage() {
        setTemplate();
        return template;
    }
}

如果你习惯字段注入,也可以把@Autowired和@Qualifier直接加在子类的config字段上,但构造注入更利于单元测试,也能明确展示类的依赖关系。

内容的提问来源于stack exchange,提问作者l0r3nz4cc10

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 22:10:27