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

使用@Autowired时抽象类子类对象为null的问题排查

问题根源与解决方案

嘿,这个问题我太熟了!你遇到的type1Processor等子类对象为null的核心原因是:你在main方法里手动new了一个ReactiveSocketServerApplication实例,这个对象完全不受Spring容器的管理。

Spring的依赖注入只对它自己创建并纳入容器的bean生效——你看到ReceivedDataService和Processor子类的构造函数被调用,是因为Spring已经悄悄创建了这些类的bean实例,但这些实例和你手动new的那个ReactiveSocketServerApplication半毛钱关系都没有,Spring根本不会去处理你手动new出来的对象上的@Autowired注解,所以那些字段自然都是null。

解决办法(推荐第一种)

方案1:让启动类实现CommandLineRunner接口

这是Spring Boot启动后执行初始化逻辑的标准做法,Spring会在容器完全初始化完成后自动调用run方法,此时所有注入的bean都已经准备就绪:

@SpringBootApplication
public class ReactiveSocketServerApplication implements CommandLineRunner {
    private AppServer appServer;

    @Autowired
    Type1Processor type1Processor;
    @Autowired
    Type2Processor type2Processor;
    @Autowired
    Type3Processor type3Processor;

    public static void main(String[] args) {
        SpringApplication.run(ReactiveSocketServerApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // 在这里执行你的启动逻辑
        startServer();
    }

    private void startServer(){
        appServer = AppServer.getInstance();
        Map<Integer, Processor> processorMap = new HashMap<>();
        processorMap.put(7001, type1Processor);
        processorMap.put(7002, type2Processor);
        processorMap.put(7003, type3Processor);
        appServer.initialize(processorMap);
        new ClientHandler(7001, 1000);
        new ClientHandler(7002, 5000);
    }
}

方案2:从Spring上下文手动获取bean

如果你非要在main方法里处理,可以通过SpringApplication.run的返回值拿到ApplicationContext,再从中取出需要的bean:

@SpringBootApplication
public class ReactiveSocketServerApplication {
    private AppServer appServer;

    public static void main(String[] args) {
        // 获取Spring上下文
        ApplicationContext context = SpringApplication.run(ReactiveSocketServerApplication.class, args);
        
        // 从上下文取出需要的bean
        Type1Processor type1Processor = context.getBean(Type1Processor.class);
        Type2Processor type2Processor = context.getBean(Type2Processor.class);
        Type3Processor type3Processor = context.getBean(Type3Processor.class);
        
        ReactiveSocketServerApplication app = new ReactiveSocketServerApplication();
        app.startServer(type1Processor, type2Processor, type3Processor);
    }

    private void startServer(Type1Processor type1Processor, Type2Processor type2Processor, Type3Processor type3Processor){
        appServer = AppServer.getInstance();
        Map<Integer, Processor> processorMap = new HashMap<>();
        processorMap.put(7001, type1Processor);
        processorMap.put(7002, type2Processor);
        processorMap.put(7003, type3Processor);
        appServer.initialize(processorMap);
        new ClientHandler(7001, 1000);
        new ClientHandler(7002, 5000);
    }
}

小补充:抽象类的@Component注解

你的抽象类Processor没有加@Component,不过因为子类都标注了@Component,Spring会正常扫描并创建子类的bean,这部分没问题。如果后续需要让抽象类作为组件基类被Spring识别,也可以给它加上@Component(不是必须的)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:37:52