TaskScheduler 的 NullPointerException

问题描述 投票:0回答:2

我有一个 TaskScheduler 类,如下所示:

public class NotificationManger {

@Autowired
private TaskScheduler scheduler;

private ScheduledFuture<?> sc;

public NotificationManger(WebSocketMessage webSocketMessage, String userName, Date date, Date time) {
    scheduleTask(webSocketMessage, userName, combine(date,time));
}

public void scheduleTask(WebSocketMessage webSocketMessage, String userName, Date startTime) 
  { 
    Runnable r = new NotificationSenderTask(webSocketMessage, userName);

    sc = scheduler.schedule(r, new Date());//here I get a  NullPointerException 
  
   }
}

和一个 Runnable 类,如下所示:

class NotificationSenderTask implements Runnable {

@Autowired
SimpMessagingTemplate webSocketMessageTemplate;

private String userName;

private WebSocketMessage webSocketMessage;

public NotificationSenderTask(WebSocketMessage webSocketMessage, String userName) {
    this.webSocketMessage = webSocketMessage;
    this.userName = userName;
}

public void run() {

    webSocketMessageTemplate.convertAndSendToUser(userName, "/notification", webSocketMessage);;
}

}

我调用TaskScheduler

NotificationManger mn = new NotificationManger(new WebSocketMessage(n), user.getEmail(),date1,date2 );

但我越来越

java.lang.NullPointerException: null

sc = scheduler.schedule(r, new Date());

也许我使用的可运行类是错误的?

@EnableWebMvc
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
@Configuration
@ComponentScan(basePackages = "gestionprojet.java")
@PropertySource("classpath:application.properties")
@Import({PersistenceJPAConfig.class, WebSecurityConfig.class})
public class WebConfig extends WebMvcConfigurerAdapter {...}
java spring nullpointerexception scheduled-tasks
2个回答
2
投票

AutowireHelper 来救援

OP 实际上找到了一个库来强制自动装配到非 spring 管理的 bean 中,而不是重构所有代码:

该库是:https://github.com/alv-ch/alv-ch-java

可以这样使用:

public class NotificationManager {
    @Autowired
    private TaskScheduler scheduler;

    public NotificationManager(WebSocketMessage webSocketMessage, String userName, Date date, Date time) {
        AutowireHelper.autowire(this, scheduler);
        scheduleTask(webSocketMessage, userName, combine(date,time));
    }
    ...
}

这会将

TaskScheduler
自动连接到
NotificationManager
,即使它不是 spring 管理的。 您可以在这里查看 AutowireHelper 源代码。


另一种可能的解决方案

1.使用@Service注释NotificationManager并删除构造函数:

@Service
public class NotificationManager {

    @Autowired
    private TaskScheduler scheduler;

    private ScheduledFuture<?> sc;

    public void scheduleTask(WebSocketMessage webSocketMessage, String userName, Date date, Date time) {
        scheduleTask(webSocketMessage, userName, combine(date,time));
    }

    public void scheduleTask(WebSocketMessage webSocketMessage, String userName, Date startTime) 
    { 
        Runnable r = new NotificationSenderTask(webSocketMessage, userName);
        sc = scheduler.schedule(r, new Date());

   }
}

2.自动装配通知管理器

然后,在您以前执行

NotificationManager mn = new NotificationManager(...)
的位置,执行以下操作:

@Autowired 
private NotificationManager notificationManager;

...
notificationManager.scheduleTask(new WebSocketMessage(n), user.getEmail(),date1,date2);

为了使其工作,无论它在哪里,它也需要位于 spring 管理的 bean 内。


-2
投票

你还没有初始化全局实例变量

私有TaskScheduler调度程序;

由于它是一个全局实例变量,因此不会给出任何编译时错误,并且隐式地使用 null 值进行初始化。

这就是为什么当你尝试访问scheduler.schedule时它会抛出空指针错误。

希望这能解决您的疑问。

© www.soinside.com 2019 - 2024. All rights reserved.