Spring 启动 Rabbitmq AMQP & WebSocket NULL 指针异常
Spring Boot Rabbitmq AMQP & WebSocket NULL pointer exception
我正在尝试在用户连接建立后立即在 WebSocketHandler 中使用 Rabbitmq 发送消息。问题是,Rabbitmq 生产者 bean 为空。
从 Controller 调用生产者工作得很好,但是当我尝试从 WebSocketHandler bean 调用它时,如果失败并出现 NULL 指针异常:
WebSocket 配置:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyWebSocketHandler(), "/connect");
}
}
WebSocket 处理程序 bean,其中 NULL 指针异常 heppens:
@Component
public class MyWebSocketHandler extends TextWebSocketHandler {
private static final Logger LOG = LoggerFactory.getLogger(WebSocketConfig.class);
@Autowired
QueueProducer producer; //NULL
List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.add(session);
List<String> lol = session.getHandshakeHeaders().get("User-Agent");
//Calling the rabbitmq producer
producer.produce("Hi Mark");//NULL
}
Rabbitmq 配置:
@Configuration
public class RabbitConfiguration {
@Value("${fanout.exchange}")
private String fanoutExchange;
@Value("${queue.name}")
private String queueName;
@Bean
Queue queue() {
return new Queue(queueName, true);
}
@Bean
FanoutExchange exchange() {
return new FanoutExchange(fanoutExchange);
}
@Bean
Binding binding(Queue queue, FanoutExchange exchange) {
return BindingBuilder.bind(queue).to(exchange);
}
}
Rabbitmq 生产者代码:
@Component
public class QueueProducer {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Value("${fanout.exchange}")
private String fanoutExchange;
private final RabbitTemplate rabbitTemplate;
@Autowired
public QueueProducer(RabbitTemplate rabbitTemplate) {
super();
this.rabbitTemplate = rabbitTemplate;
}
public void produce(String message) throws Exception {
logger.info("Storing notification...");
rabbitTemplate.setExchange(fanoutExchange);
rabbitTemplate.convertAndSend(message);
logger.info("Notification stored in queue sucessfully");
}
}
堆栈跟踪:
java.lang.NullPointerException: null
at com.ta9.common.Config.MyWebSocketHandler.afterConnectionEstablished(MyWebSocketHandler.java:43) ~[classes/:na]
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.afterConnectionEstablished(WebSocketHandlerDecorator.java:70) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.afterConnectionEstablished(LoggingWebSocketHandlerDecorator.java:48) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.afterConnectionEstablished(ExceptionWebSocketHandlerDecorator.java:48) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.onOpen(StandardWebSocketHandlerAdapter.java:104) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:135) ~[tomcat-embed-websocket-9.0.48.jar:9.0.48]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:940) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
提前致谢。
这是预期的行为。
让我们再看一遍您的代码:
registry.addHandler(new MyWebSocketHandler(), "/connect");
你看你手动new
。你不依赖这里的依赖注入容器。在这种情况下,您的 MyWebSocketHandler
不是一个 bean。因为它被标记为 @Component
我想它被正确扫描并使其作为一个 bean 在应用程序上下文中可用。所以,也许你可以这样做来解决你的问题:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
MyWebSocketHandler myWebSocketHandler;
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(this.myWebSocketHandler, "/connect");
}
}
我正在尝试在用户连接建立后立即在 WebSocketHandler 中使用 Rabbitmq 发送消息。问题是,Rabbitmq 生产者 bean 为空。 从 Controller 调用生产者工作得很好,但是当我尝试从 WebSocketHandler bean 调用它时,如果失败并出现 NULL 指针异常:
WebSocket 配置:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyWebSocketHandler(), "/connect");
}
}
WebSocket 处理程序 bean,其中 NULL 指针异常 heppens:
@Component
public class MyWebSocketHandler extends TextWebSocketHandler {
private static final Logger LOG = LoggerFactory.getLogger(WebSocketConfig.class);
@Autowired
QueueProducer producer; //NULL
List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessions.add(session);
List<String> lol = session.getHandshakeHeaders().get("User-Agent");
//Calling the rabbitmq producer
producer.produce("Hi Mark");//NULL
}
Rabbitmq 配置:
@Configuration
public class RabbitConfiguration {
@Value("${fanout.exchange}")
private String fanoutExchange;
@Value("${queue.name}")
private String queueName;
@Bean
Queue queue() {
return new Queue(queueName, true);
}
@Bean
FanoutExchange exchange() {
return new FanoutExchange(fanoutExchange);
}
@Bean
Binding binding(Queue queue, FanoutExchange exchange) {
return BindingBuilder.bind(queue).to(exchange);
}
}
Rabbitmq 生产者代码:
@Component
public class QueueProducer {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Value("${fanout.exchange}")
private String fanoutExchange;
private final RabbitTemplate rabbitTemplate;
@Autowired
public QueueProducer(RabbitTemplate rabbitTemplate) {
super();
this.rabbitTemplate = rabbitTemplate;
}
public void produce(String message) throws Exception {
logger.info("Storing notification...");
rabbitTemplate.setExchange(fanoutExchange);
rabbitTemplate.convertAndSend(message);
logger.info("Notification stored in queue sucessfully");
}
}
堆栈跟踪:
java.lang.NullPointerException: null
at com.ta9.common.Config.MyWebSocketHandler.afterConnectionEstablished(MyWebSocketHandler.java:43) ~[classes/:na]
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.afterConnectionEstablished(WebSocketHandlerDecorator.java:70) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.afterConnectionEstablished(LoggingWebSocketHandlerDecorator.java:48) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.afterConnectionEstablished(ExceptionWebSocketHandlerDecorator.java:48) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.onOpen(StandardWebSocketHandlerAdapter.java:104) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:135) ~[tomcat-embed-websocket-9.0.48.jar:9.0.48]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:940) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.48.jar:9.0.48]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
提前致谢。
这是预期的行为。 让我们再看一遍您的代码:
registry.addHandler(new MyWebSocketHandler(), "/connect");
你看你手动new
。你不依赖这里的依赖注入容器。在这种情况下,您的 MyWebSocketHandler
不是一个 bean。因为它被标记为 @Component
我想它被正确扫描并使其作为一个 bean 在应用程序上下文中可用。所以,也许你可以这样做来解决你的问题:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
MyWebSocketHandler myWebSocketHandler;
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(this.myWebSocketHandler, "/connect");
}
}