ssm整合在controller层用@Autowired自动装配service层对象时报错“No Beans Of ‘UserService‘ type found”

问题原因:MVC配置类的注解@ComponentScan("com.example.controller")扫描controller包时发现当前尚未有service层的对象?

解决方案:项目正常启动和正常访问,暂不处理

### 实现 SSM 框架中的自动装配Spring 中,自动装配(autowiring)是一种依赖注入的方式,它允许容器管理对象之间的关系而无需显式的 setter 或者构造器注入。为了使 SSM 框架能够支持自动装配功能,在配置文件中需要启用组件扫描以及定义相应的 Bean。 #### 配置 `applicationContext.xml` 文件来启动组件扫描并设置包路径: ```xml <context:component-scan base-package="com.example.ssm"/> ``` 此行代码会告诉 Spring 容器去查找指定基础包及其子包下带有特定注解的类,并将其注册为 Spring 的 Bean[^1]。 对于 MyBatis 和 Spring 整合部分,则可以通过如下方式完成 Mapper 接口的自动发现与映射: ```xml <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.ssm.mapper"/> </bean> ``` 上述 XML 片段用于指示 MyBatis-Spring 扩展库寻找给定的基础包内的所有接口作为 mapper 并创建对应的代理实例。 接下来展示一个简单的例子说明如何利用这些特性简化开发过程: 假设有一个名为 `UserMapper.java` 的 DAO 接口负责处理数据库操作;还有一个服务逻辑实现类 `UserService.java`; 最后是一个控制器 `UserController.java`. - **DAO Layer (MyBatis)**: ```java package com.example.ssm.mapper; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; @Repository // 将该类标记为持久化组件 public interface UserMapper { @Select("SELECT * FROM users WHERE id=#{id}") User getUserById(int id); @Insert("INSERT INTO users(name,email,password) VALUES(#{name}, #{email}, #{password})") void insertUser(User user); } ``` - **Service Layer**: ```java package com.example.ssm.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service // 注册成业务逻辑的服务组件 public class UserService { private final UserMapper userMapper; @Autowired // 自动注入已存在的 bean 到当前属性上 public UserService(UserMapper userMapper){ this.userMapper = userMapper; } public User findUserById(Integer userId){ return userMapper.getUserById(userId); } } ``` - **Web Controller**: ```java package com.example.ssm.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController // 组合了@Controller和@ResponseBody两个注解的作用 @RequestMapping("/users") public class UserController { private final UserService userService; @Autowired // 构造函数注入优于字段级或setter方法级别的注入 public UserController(UserService userService){ this.userService = userService; } @GetMapping("/{userId}") public ResponseEntity<User> getUser(@PathVariable Integer userId){ try{ User user = userService.findUserById(userId); if(user != null){ return new ResponseEntity<>(user, HttpStatus.OK); }else{ throw new ResourceNotFoundException(); } }catch(Exception e){ logger.error(e.getMessage()); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } } ``` 通过以上配置和编码实践可以显著减少样板代码的数量,提高项目的可维护性和扩展性。值得注意的是,在实际项目中应当遵循最佳实践原则合理运用自动装配机制,比如优先考虑基于类型的构造参数注入而非字段级别或者 Setter 方法级别的注入形式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值