@Autowired 注入失败等问题

问题1 @Autowired 注入失败

image.png

@Autowired
    private DingService dingService;

在项目中service是用 @Autowired依赖注入,用debug测试的时候看到service确实为null。

一开始想法:想用new的形式手动生成一个service,但是在查找资料之后发现这种方式是有弊端的,于是不采用。

DingServiceImpl dingService1 = new DingServiceImpl();

弊端:在spring中如果使用new创建一个对象时,这个对象将不在受spring管理器管理,这样的话就绕过了容器的依赖注入过程,也可能出现获取不到应有的属性这种情况。
说明:Spring是一个bean的容器,由容器负责对象的初始化和依赖注入。当我们想要从中获取一个Bean的实例时,就从Spring容器中获取。


最后查找资料之后发现原因:
@EntityListeners(LogListener.class)
这里是在Listener中使用了@Autowired,导致的注入失败。

在应用的Filter或Listener中使用了@Autowired ,注入为空web容器启动是按照一定顺序的,即:Listener --> Filter -->Servlet。
因为Filter和Listener加载顺序优先于spring容器初始化实例,所以会出现null。Spring的入口就在Servlet里。可以用ApplicationContext根据bean名称(注意名称为实现类而不是接口)去获取bean。

之前学长就采用的这种方法:ApplicationContext去获取bean。
传送门:https://segmentfault.com/a/11...

这种方法需要新建文件,自定义实现ApplicationContextAware。

对于Listener来说,我找到了一种更方便一点的方法,不需要新建文件来实现类。

@Component
public class LogListener implements ServletContextListener {

    @Autowired
    private DingService dingService;
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext())
                .getAutowireCapableBeanFactory().autowireBean(this);
    }

只要继承ServletContextListener,并在在监听类的contextInitialized的方法中加上如上代码即可。
原理是一样的,都是从ApplicationContext中获取bean.

总结一下@Autowired为null的几种情况:
1.在应用的Filter或Listener中使用了@Autowired
2.组件上面没有加入了合适的注解。例如:@Service, @Component等,Bean没有交付给Spring容器。
3.把@Autowired注解加在了一个静态属性上,注入为空
4.检查@Autowired注入类使用的方法是否为private,如果为private的话在生成动态代理的话@Autowired注入的依赖将为空。
5.检查本文件中是不是new了一个对象,这样的话就绕过了容器的依赖注入过程,也可能出现获取不到应有的属性这种情况。

目前对于ApplicationContext和Servlet这些还不太熟悉,待有了解之后再来补充。长路漫漫。

2.定时器误差

目前项目是2分钟发送一次定时任务,并且会判断当前发送任务是否与上次间隔2分钟,如果是则发送,这导致了本次的定时任务没有发送,可能发生一些错误。经过老师的说明和谷歌的搜索,才了解这种误差。一般会有1到2毫秒的延迟,写代码的时候需要考虑进去这种误差。
image.png

3.总结

环境也是一方面的问题:
lQLPDhsxKMSoYqN-zQFZsMJ_EXYu4_MvAiE3OV_AvwA_345_126.png
今天突然docker的mysql用不了了,之后弄了很久,重新初始化了数据库,直接在控制台跑的mysql,然后就不用docker了。

本周的主要感受就是修bug有时候很不容易,特别是别人写的代码。很多时候费时间的不是修bug的时间,而是找bug发生在哪里的问题。跑了很久的前后台,打了很多断点到控制台,才发现哪里有问题。不过这也是一种锻炼,加强了我的测试能力和阅读代码的能力。

目前解决了@Autowired的问题后,rizhi系统目前暂时没有问题。很多时间自己测试的时候没有问题,直到集成测试的时候才暴露问题,还是测试不够充分。

622 声望
104 粉丝
0 条评论
推荐阅读
为什么要有Java 内存模型,是什么, 解决了什么
Java内存模型(Java Memory Model,JMM) 定义了 java 运行时如何与硬件内存进行交互,比如规定了一个线程如何看到其他内存修改后共享变量的值。一些高级特性也建立在JMM的基础上,比如volatile 关键字。

weiweiyi3阅读 498

Spring Aop 动态代理
为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施...

KerryWu5阅读 8.7k评论 1

SpringBoot集成LibreOffice+jodconverter做文件预览(office转pdf)
LibreOffice 是一款开放源代码的自由免费全能办公软件,可运行于 Microsoft Windows, GNU/Linux 以及 macOS 等操作系统上。它包含了 Writer, Calc, Impress, Draw, Math 以及 Base 等组件,可分别用于文本文档、...

Zeran2阅读 6.3k

之前很火给女朋友推送微信服务号消息是怎么做的?
经过了几天的奋战,终于把微信服务号的模板消息给写完了。后端其实没花多少时间,因为之前已经有同学提过pull request了,我在这基础之上简单优化下就完事了,主要的时间都是花在前端上,对前端页面和参数的适配...

Java3y3阅读 1.2k

简单使用spring cloud 服务注册做一个请求转发中心
背景上篇文章 记录多项目共用一个公众号逻辑修改, 实现了多个项目共用一个公众号。 但是也存在几点问题,比如:中间服务器拦截了微信的请求,虽然方便了项目不再需要写微信授权的代码,但如果以后需要再拓展新的...

weiweiyi2阅读 795

消息推送平台终于要上线啦!
我的开源项目消息推送平台Austin终于要上线了,迎来在线演示的第一版!🔥项目在线演示地址:[链接]消息推送平台🔥推送下发【邮件】【短信】【微信服务号】【微信小程序】【企业微信】【钉钉】等消息类型。[链接][链...

Java3y3阅读 1.1k

Java项目是不是分布式,真有那么重要吗?
「微服务」「分布式」在我刚毕业的时候还是比较关注的,那时候还入门了一把SpringCloud,写了一篇很长的文章,还是很顶的,有不少的大号都给我转载了,在知乎又获得了很多的赞。

Java3y2阅读 602评论 1

622 声望
104 粉丝
宣传栏