Springboot中手动new的对象无法注入交给Spring容器管理的原因及解决办法
Springboot中Bean的注入我们都知道,Springboot可以使用方法级别注解(@Bean)和类级别注解(@Controller、@Component、@Service等)加包扫描的方式注入Beans。实现交给Spring容器管理。这样我们就能很方便的实现,在Controller中注注入Service,在Service中注入Mapper。比较常用的就是Service的注入(@Autowi
Springboot中Bean的注入
我们都知道,Springboot可以使用方法级别注解(@Bean)和类级别注解(@Controller、@Component、@Service等)加包扫描的方式注入Beans。实现交给Spring容器管理。这样我们就能很方便的实现,在Controller中注注入Service,在Service中注入Mapper。比较常用的就是Service的注入(@Autowired)与使用,我们会经常利用封装好的Service层调用dao层的接口进行业务逻辑应用的处理。比如Controller中注入Service来根据不同情况调用Service中的方法来完成功能实现。
自己new的无法注入
但是这其中有一个问题,就是当我们需要自己手动new对象的时候,这个对象对应的类是无法交给Spring管理的。这种情况通常发生在一些需要自己处理的参数,比如监听器类。我是使用阿里云EasyExcel对表格内容进行操作时碰到的。可以看到下图中参数列表中除了流的要求外还要有一个ReadListener的监听器。
大概场景就是需要把表格里的数据读取出来并且进行相应的数据库操作。这时候我们这个监听器对象Listener就会需要使用到Service层的方法区操作。按照平常,我们只需要在这个Listener类中@Autowired注入Service然后直接用就好了。但是这个Listener又无法交给Spring管理。如果我们注入就会发现会报错(应该是空指针异常),无法注入。因为@Autowired注入时是将类交给Springboot管理,而new出来的实例脱离了Springboot的管理,两个东西不在一个管理者管理下,所以没法联系在一起,@Autowired注入就会为null,就会出现空指针的情况。
解决办法
既然我们在参数中new了一个Listener,那么其实我们在new的时候就可以把Service通过参数的方式传递进去,我们就可以使用了。具体实现:首先我们得在自己的Listener中添加有参构造和无参构造(参数其实就是Service) 我们其实可以从上层调用方法的时候就一步一步的把注入的Service一步步传递过来。在我们new Listener的时候,就把Service作为参数传递进这个Listener监听器类中,那我们就可以在这个监听器中随心所欲的使用Service完成我们想要的操作了。
public class ExcelListener extends AnalysisEventListener<> {
private Service service;
public ExcelListener(Service service) {
this.service = service;
}
public ExcelListener() {
}
在这下面我们就可以重写方法完成我们想要的操作了。
这其实是一个很简单的操作,理解原理其实不难想到。所以我们更应多理解底层实现和原理,分享出来也是为了大家一起学习共同进步。
结尾
最后强烈建议大家学习Springboot的自动装配原理,以及@SpringBootApplication,@EnableAutoConfiguration,@Configuration,@SpringBootConfiguration,@ComponentScan,@Component 这些核心注解的原理和作用。因为在初学的过程中,其实很多小伙伴会因为注解出现各种各样的错误,比如@ComponentScan对于路径的扫描的问题,很多错误是找到某某某,或者空指针等等,都是Spring没有找到这些东西导致的,很有可能就是你的配置错误,注解没用或者路径不对的问题,所以对于这些注解和原理我们还是需要深入了解的。
以上只是个人学习中一些感悟与分享,如有错误欢迎指正与交流。
更多推荐
所有评论(0)