关于springboot:本周解决的一些问题

3次阅读

共计 1690 个字符,预计需要花费 5 分钟才能阅读完成。

问题 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 来说,我找到了一种更不便一点的办法,不须要新建文件来实现类。

@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 毫秒的提早,写代码的时候须要思考进去这种误差。

3. 双线程导致的问题

解决:在保留前对数据库从新获取最初交互工夫字段

正文完
 0