在非标准Spring组件中(比如websocket)注入Spring管理bean的方法

private static UserMapper userMapper;
    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        WebSocketServer.userMapper = userMapper;
    }

WebSocketServer是通过Java WebSocket API创建的,并且由于@ServerEndpoint不是Spring的标准组件注解,直接在其中使用@Autowired进行依赖注入通常是行不通的。这就需要采用一种特殊的方式来实现依赖注入。

private static UserMapper userMapper;:这是对UserMapper的静态声明。UserMapper是一个接口,通过MyBatis或MyBatis Plus等ORM框架与数据库进行交互的Mapper。由于WebSocketServer实例可能会有多个,而UserMapper应该是一个全局单例(与数据库的交互通常是线程安全的,且不需要每个WebSocket连接都创建一个新的实例),因此这里使用static修饰符。

(ORM框架:允许开发者在编程时使用面向对象的方式来操作数据库中的数据,而不是通过直接编写SQL语句。ORM框架会负责将面向对象的操作转换为适当的数据库操作。)

@Autowired:这是Spring的注解,用于自动注入依赖。但是由于WebSocketServer类的实例化不是由Spring控制的,因此不能直接在类的字段上使用@Autowired进行自动注入。

public void setUserMapper(UserMapper userMapper) { ... }:这个方法是一个通过@Autowired注解的setter方法。Spring会自动调用这个方法并传入一个UserMapper的实例,这样即使在非标准的Spring组件中也能实现依赖注入。这里通过传递的userMapper参数来设置静态字段userMapper的值。

解决方案

为了在WebSocketServer这样的类中注入Spring管理的bean,解决方案是创建一个非静态的setter方法,并在这个方法上使用@Autowired注解。Spring在启动时会自动调用这个方法,并注入所需的依赖。然后,这个方法内部再将注入的依赖赋值给静态变量,这样即便是WebSocket的生命周期管理不由Spring控制,我们也能在类中使用由Spring管理的依赖。

注意事项

使用静态字段持有Spring管理的bean是一种特殊情况下的解决方案,通常不推荐这样做,因为它违背了Spring的依赖注入原则,可能会导致代码难以测试和维护。不过,在某些特殊场景(如此处的WebSocket服务端实现)下,这种方式可以作为一种权宜之计。

posted @ 2024-03-20 20:49  r涤生  阅读(20)  评论(0编辑  收藏  举报