参考链接
监听器Listener中使用spring容器管理的bean,解决Autowired为null空指针的问题_listener无法获取容器内bean-CSDN博客
先说结论,原因是ExcelReader是手动new出来的对象,不被Spring管理
这个链接中写到
首先要区分Listener的生命周期和spring管理的bean的生命周期。
(1)Listener的生命周期是由servlet容器(例如tomcat)管理的,项目启动时上例中的ConfigListener是由servlet容器实例化并调用其contextInitialized方法,而servlet容器并不认得@Autowired注解,因此导致ConfigService实例注入失败。
(2)而spring容器中的bean的生命周期是由spring容器管理的。
在web Server容器中,无论是Servlet,Filter,还是Listener都不是Spring容器管理的,因此我们都无法在这些类中直接使用Spring注解的方式来注入我们需要的对象
这是不正确的,并不是Listener的原因,一层一层点开Listener的父类,发现并没有实现或继承servlet的ServletContextListener
package com.alibaba.excel.event;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ConverterUtils;
import java.util.Map;
public abstract class AnalysisEventListener<T> implements ReadListener<T> {
public AnalysisEventListener() {
}
....
}
package com.alibaba.excel.read.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.Listener;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.metadata.data.ReadCellData;
import java.util.Map;
public interface ReadListener<T> extends Listener {
...
}
package com.alibaba.excel.event;
public interface Listener {
}
那么可以确定AnalysisEventListener并不是被Servlet容器管理的,参考文献的原因是错误的
那究竟是什么原因导致EasyExcel不被Spring管理的呢?打开EasyExcel的build方法和doReadAll方法,可以看到这两个方法都是new 一个新的实例,这就涉及很基础的问题了,手动new的对象是不被Spring容器管理的,所以无法使用@Autowired注入。
public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder<ExcelReaderBuilder, ReadWorkbook> {
private ReadWorkbook readWorkbook = new ReadWorkbook();
public ExcelReaderBuilder() {
}
...
public ExcelReader build() {
return new ExcelReader(this.readWorkbook);
}
public void doReadAll() {
ExcelReader excelReader = this.build();
excelReader.readAll();
excelReader.finish();
}
...
}
解决方案可以参照参考链接,通过构造函数传入Service的引用对象或者从Spring上下文中取得引用对象。