spring mapper注入到service失败的解决方法

今天遇到一个奇异的问题, 我在service 中可以正常的@Autowired注入mapper,但是在我们另外一个项目无法通过@Autowired注入mapper

1)@Autowired
注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。如下:
@Autowired
@Qualifier(“userMapper”)
private UserMapper userMapper;

2)@Resource
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
那么问题,貌似找到了,我们@Repository(“userMapper”),指定了名字来管理(byName)来给spring管理,而@Autowired默认是按照类型(byType)来注入对象的,回忆一下
所以,改用@Resouce以后,spring就可也根据名字(byName)来注入成功。
如果的确还想用@Autowired来注入,那么久必须和@Qualifier配合使用,直接定名字。

最终问题得以解决,但最终为什么还没太弄明白,待详细研究。
转载:https://blog.youkuaiyun.com/afsvsv/article/details/78771591

### SpringBoot 中 WebSocket Mapper 注入失败的原因分析 在 SpringBoot 项目中,WebSocket 的 Bean 是多例的(即每次客户端连接都会创建一个新的 WebSocket 对象),而 Spring 容器中的其他 Bean 默认是单例的。由于 WebSocket 的生命周期是由客户端连接触发的,而不是由 Spring 容器管理的,因此在 WebSocket 初始化时无法直接注入依赖于 Spring 容器管理的 Bean,比如 MyBatis 的 Mapper。 #### 解决方案一:使用 ApplicationContext 获取 Bean 可以利用 `ApplicationContext` 动态获取所需的 Bean。通过这种方式,在 WebSocket 运行期间手动从 Spring 容器中获取 Mapper 或者 Service 层的对象。 以下是具体实现方法: ```java @Component public class MyWebSocketHandler extends TextWebSocketHandler { private final ApplicationContext applicationContext; public MyWebSocketHandler(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 使用 ApplicationContext 手动获取 Mapper UserMapper userMapper = applicationContext.getBean(UserMapper.class); // 调用 Mapper 方法 List<User> users = userMapper.getAllUsers(); System.out.println(users); super.handleTextMessage(session, message); } } ``` 此方式适用于需要动态加载 Bean 场景[^1]。 --- #### 解决方案二:将 WebSocket 配置为单例模式并延迟初始化 如果希望保持 WebSocket 单例模式,则可以在其内部定义一个懒加载机制来处理依赖注入问题。例如,通过代理类或者工厂方法完成对 Mapper 的访问。 下面是一个基于 Factory Pattern 的例子: ```java @Component public class WebSocketFactory { @Autowired private UserMapper userMapper; public UserMapper getUserMapper() { return userMapper; } } @Component public class MyWebSocketHandler extends TextWebSocketHandler { @Autowired private WebSocketFactory webSocketFactory; @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 通过工厂类间接调用 Mapper UserMapper userMapper = webSocketFactory.getUserMapper(); // 查询数据库操作 List<User> users = userMapper.getAllUsers(); System.out.println(users); super.handleTextMessage(session, message); } } ``` 这种方法能够有效分离 WebSocket 和 Mapper 的耦合关系[^2]。 --- #### 解决方案三:调整 WebSocket 生命周期至 Spring 管理范围 另一种思路是让 WebSocket 成为 Spring 容器完全托管的一个组件。这样就可以像普通 Controller 类一样正常注入 Mapper 或服务层逻辑。 修改后的代码如下所示: ```java @Component public class MyWebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myWebSocketHandler(), "/websocket").setAllowedOrigins("*"); } @Bean public WebSocketHandler myWebSocketHandler() { return new MyWebSocketHandler(); } } @Component public class MyWebSocketHandler extends TextWebSocketHandler { @Autowired private UserMapper userMapper; @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 正常调用已注入Mapper List<User> users = userMapper.getAllUsers(); System.out.println(users); super.handleTextMessage(session, message); } } ``` 上述配置使得 WebSocket 可以被 Spring 容器统一管理,并支持标准的 DI 模型[^3]。 --- ### 总结 以上三种方法分别针对不同场景提供了灵活的选择: - 如果仅需临时获取某个特定 Bean,推荐 **解决方案一**; - 若涉及复杂业务流程且不希望增加额外依赖,可采用 **解决方案二**; - 若要彻底融入 Spring 生态体系,则应优先考虑 **解决方案三**。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值