本周解决的一些问题

问题1 @Autowired 注入失败

本周解决的一些问题_第1张图片

@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毫秒的延迟,写代码的时候需要考虑进去这种误差。
本周解决的一些问题_第2张图片

3.双线程导致的问题

本周解决的一些问题_第3张图片

解决:在保存前对数据库重新获取最后交互时间字段

4.总结

环境也是一方面的问题:
本周解决的一些问题_第4张图片
今天突然docker的mysql用不了了,之后弄了很久,重新初始化了数据库,直接在控制台跑的mysql,然后就不用docker了。

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

你可能感兴趣的:(springboot)