Spring Events中ApplicationEventPublisher空指针异常问题求助
Spring Events 空指针异常问题解决
我是Spring和SpringBoot初学者,正在学习Spring Events。调用publishEvent()方法时反复出现ApplicationEventPublisher对象的空指针异常。
事件类代码
public class EventClass extends ApplicationEvent { private String message; public EventClass(Object source, String message) { super(source); this.message = message; } public String getMessage() { return message; } }
事件发布类代码
@Service public class PublishEvents { @Autowired private ApplicationContext applicationContext; public void publishEvent(String message){ System.out.println("Publishing events..."); EventClass event = new EventClass(this,message); applicationContext.publishEvent(event); } }
监听器类代码
@Component public class ListenerClass implements ApplicationListener<EventClass> { @Override public void onApplicationEvent(EventClass event) { System.out.println("Listener received messages..." + event.getMessage()); } }
主类代码(存在问题的版本)
@SpringBootApplication public class SpringeventsApplication { public static void main(String[] args) { SpringApplication.run(SpringeventsApplication.class, args); springEvents(); } public static void springEvents(){ PublishEvents publishMessage = new PublishEvents(); publishMessage.publishEvent("Hi I think this works..."); } }
问题原因
核心问题是手动通过new PublishEvents()创建对象,这个对象不在Spring容器的管理范围内,Spring不会为其注入@Autowired标记的ApplicationContext,因此调用publishEvent()时会触发空指针异常。
解决方案
1. 修正主类代码,从Spring容器获取Bean
不要手动实例化PublishEvents,而是从Spring应用上下文中获取容器管理的Bean:
@SpringBootApplication public class SpringeventsApplication { public static void main(String[] args) { // 获取Spring应用上下文 ConfigurableApplicationContext context = SpringApplication.run(SpringeventsApplication.class, args); // 从容器中获取PublishEvents实例 PublishEvents publishMessage = context.getBean(PublishEvents.class); publishMessage.publishEvent("Hi I think this works..."); } }
2. 优化事件发布类:直接注入ApplicationEventPublisher
ApplicationContext继承了ApplicationEventPublisher,但直接注入ApplicationEventPublisher更贴合事件发布的单一职责,代码更清晰:
@Service public class PublishEvents { @Autowired private ApplicationEventPublisher eventPublisher; public void publishEvent(String message){ System.out.println("Publishing events..."); EventClass event = new EventClass(this, message); eventPublisher.publishEvent(event); } }
3. 简化监听器:使用@EventListener注解
无需实现ApplicationListener接口,直接用@EventListener标记处理事件的方法,代码更简洁灵活:
@Component public class ListenerClass { @EventListener public void handleEvent(EventClass event) { System.out.println("Listener received messages..." + event.getMessage()); } }
内容的提问来源于stack exchange,提问作者Meghna Sinha
相关产品推荐
相关产品推荐

