问题1 @Autowired 注入失败
@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来说,我找到了一种更不便一点的办法,不须要新建文件来实现类。
@Componentpublic 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毫秒的提早,写代码的时候须要思考进去这种误差。
3.双线程导致的问题
解决:在保留前对数据库从新获取最初交互工夫字段