java小菜一枚 2024-05-17 18:45 采纳率: 89.1%
浏览 13
已结题

注入service失败

异常信息

java.lang.NullPointerException: Cannot invoke "top.guli.allutiladmintrailing.service.IAdminService.getAdminById(String)" because "this.iAdminService" is null
    at top.guli.allutiladmintrailing.ws.StatusEndpoint.onOpen(StatusEndpoint.java:47) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:67) ~[tomcat-embed-websocket-10.1.19.jar:10.1.19]
    at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:46) ~[tomcat-embed-websocket-10.1.19.jar:10.1.19]
    at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:131) ~[tomcat-embed-websocket-10.1.19.jar:10.1.19]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:938) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.19.jar:10.1.19]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

我的代码

@ServerEndpoint("/adminStatus/{adminId}")
@Component
public class StatusEndpoint {

    private static final Map<String,Session> USER_LIST = new ConcurrentHashMap<>();

    private String adminId;

    @Autowired
    private IAdminService iAdminService;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config,@PathParam("adminId") String adminId) {
        this.adminId = adminId;
        USER_LIST.put(this.adminId,session);
        AdminEntity adminById = this.iAdminService.getAdminById(this.adminId);
        if (!ObjectUtils.isEmpty(adminById)) {
            String message = JSON.toJSONString(adminById);
            try {
                session.getBasicRemote().sendText(message);
            } catch (IOException ie) {
                ie.printStackTrace();
            }
        }
    }

    @OnMessage
    public void onMessage(String message) {
        System.out.println("收到" + this.adminId + "消息:" + message);
    }

    @OnClose
    public void onClose(Session session) {
        USER_LIST.remove(this.adminId);
    }

}

我想在这里注入service,然后发送消息给前端,但是我这样注入为null,我不是交给spring管理了吗?为什么还会为null?

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2024-05-17 18:52
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    您想要解决的问题

    您提问的目的是解决在Spring Boot应用中,尝试在WebSocket的StatusEndpoint类中注入IAdminService服务时出现NullPointerException的问题。您希望了解为什么即使您使用了@Autowired注解,iAdminService仍然为null,以及如何解决这个问题。

    问题出现原因

    问题出现的原因是Spring容器尚未初始化或未注入IAdminService时,StatusEndpointonOpen方法已经被调用。这通常发生在以下几种情况:

    1. StatusEndpoint是一个WebSocket端点,它可能在Spring容器完全启动之前就已经被Tomcat或其他Servlet容器初始化。
    2. @ServerEndpoint注解的类不属于Spring管理的Bean,因此Spring的依赖注入不会自动应用到这些类上。

    问题解决方案

    要解决这个问题,您可以尝试以下几种方法:

    1. 确保Spring容器初始化完成后再使用IAdminService:您可以使用ApplicationListener来监听Spring的ContextRefreshedEvent,确保在Spring容器初始化完成后再处理WebSocket消息。

    2. 使用@PostConstruct注解:在StatusEndpoint类中使用@PostConstruct注解的方法来确保在依赖注入完成后再进行操作。

    3. StatusEndpoint作为一个Spring管理的Bean:如果可能,您可以将StatusEndpoint作为一个Spring Bean来管理,并通过Spring的配置来注入所需的服务。

    4. 使用配置好的服务实例:在Spring配置中配置一个IAdminService的实例,并将其传递给StatusEndpoint

    提供代码

    以下是使用@PostConstruct注解的一个示例代码:

    @ServerEndpoint("/adminStatus/{adminId}")
    @Component
    public class StatusEndpoint {
    
        private static final Map<String, Session> USER_LIST = new ConcurrentHashMap<>();
        private String adminId;
        private IAdminService iAdminService;
    
        @Autowired
        public void setIAdminService(IAdminService iAdminService) {
            this.iAdminService = iAdminService;
        }
    
        @PostConstruct
        public void init() {
            // 确保iAdminService已经被注入
            if (this.iAdminService == null) {
                throw new IllegalStateException("IAdminService is not injected");
            }
        }
    
        @OnOpen
        public void onOpen(Session session, EndpointConfig config, @PathParam("adminId") String adminId) {
            this.adminId = adminId;
            USER_LIST.put(this.adminId, session);
            // 由于@PostConstruct保证了服务的注入,这里可以放心使用iAdminService
            AdminEntity adminById = this.iAdminService.getAdminById(this.adminId);
            // ... 其余代码
        }
    
        // ... 其余方法
    }
    

    代码运行方式

    • 确保您的Spring Boot应用已经正确配置,并且IAdminService已经被注册为Spring容器的一个Bean。
    • 运行您的Spring Boot应用,启动Tomcat或其他Servlet容器。

    代码预期运行结果

    当WebSocket连接打开时,StatusEndpointonOpen方法将被调用,并且iAdminService将不会是null,因为已经在@PostConstruct注解的方法中进行了验证。

    推荐相关链接

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月6日
  • 已采纳回答 5月29日
  • 创建了问题 5月17日

悬赏问题

  • ¥15 adv找不到可向其添加属性的有效项目。
  • ¥15 cesm2.2.0移植问题。./manage_externals/checkout_externals
  • ¥15 ntp对时中的时标问题
  • ¥35 pcb上电后,不一会儿,主控过热烧毁
  • ¥15 ubuntu,windows,文件传输,Linux
  • ¥15 北斗定位,cors,无人机,图传
  • ¥15 Unity热更新框架问题
  • ¥20 如何提交icra的附录.应该在哪里提交
  • ¥20 请教yolov8出现如下bug怎么办
  • ¥30 Armoury Crate 无法打开链接然后卸载了无法安装回去