即使不允许使用 @Autowired. 构造函数注入(Constructor Injection) ←【官方最推荐】
构造函数
com.ruoyi.project.system
├── controller
│ └── SysPostController.java ← 控制器
├── service
│ ├── ISysPostService.java ← 服务接口
│ └── impl
│ └── SysPostServiceImpl.java ← 服务实现
├── mapper
│ └── SysPostMapper.java ← 数据访问层
└── domain
└── SysPost.java ← 实体类
实体类
java
package com.ruoyi.project.system.domain;
import java.io.Serializable;
public class SysPost implements Serializable {
private Long postId;
private String postCode;
private String postName;
// 其他字段...
// Getter / Setter(省略,实际需生成)
public Long getPostId() { return postId; }
public void setPostId(Long postId) { this.postId = postId; }
public String getPostCode() { return postCode; }
public void setPostCode(String postCode) { this.postCode = postCode; }
public String getPostName() { return postName; }
public void setPostName(String postName) { this.postName = postName; }
}
mapper
java
package com.ruoyi.project.system.mapper;
import com.ruoyi.project.system.domain.SysPost;
import java.util.List;
// 注意:这里不需要 @Mapper,由 @MapperScan 统一管理
public interface SysPostMapper {
/**
* 查询岗位列表
*/
List<SysPost> selectPostList(SysPost post);
}
xml
java
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.project.system.mapper.SysPostMapper">
<select id="selectPostList" parameterType="SysPost" resultType="SysPost">
SELECT post_id, post_code, post_name
FROM sys_post
WHERE 1=1
<!-- 可加动态条件 -->
</select>
</mapper>
服务接口
java
package com.ruoyi.project.system.service;
import com.ruoyi.project.system.domain.SysPost;
import java.util.List;
public interface ISysPostService {
/**
* 获取所有岗位列表
*/
List<SysPost> getPosts();
}
服务实现
java
package com.ruoyi.project.system.service.impl;
import com.ruoyi.project.system.mapper.SysPostMapper;
import com.ruoyi.project.system.domain.SysPost;
import com.ruoyi.project.system.service.ISysPostService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysPostServiceImpl implements ISysPostService {
private final SysPostMapper postMapper;
// 构造函数注入(无需 @Autowired)
public SysPostServiceImpl(SysPostMapper postMapper) {
this.postMapper = postMapper;
}
@Override
public List<SysPost> getPosts() {
// 调用 Mapper 查询全部岗位
return postMapper.selectPostList(new SysPost());
}
}
控制器
java
package com.ruoyi.project.system.controller;
import com.ruoyi.project.system.domain.SysPost;
import com.ruoyi.project.system.service.ISysPostService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/post")
public class SysPostController {
private final ISysPostService postService;
// 构造函数注入(Spring 自动提供实现类)
public SysPostController(ISysPostService postService) {
this.postService = postService;
}
@GetMapping("/list")
public List<SysPost> getPosts() {
// 调用 Service 层方法
return postService.getPosts(); // ← 最终会执行 Mapper 的 SQL
}
}
步骤 1:Spring 扫描组件
你的 SysPostController 上有 @RestController(隐含 @Component)
你的 SysPostServiceImpl 上有 @Service
Spring 在启动时通过 组件扫描(Component Scan) 发现这两个类
步骤 2:注册 Bean 定义
Spring 会为它们创建 BeanDefinition(Bean 的"蓝图"):
sysPostController → 类型为 SysPostController
sysPostServiceImpl → 类型为 ISysPostService 的实现类
步骤3:按依赖顺序创建 Bean
Spring 会分析依赖关系,先创建被依赖的 Bean:
先创建 SysPostServiceImpl
它依赖 SysPostMapper
而 SysPostMapper 已被 @MapperScan 注册为 Bean(名为 sysPostMapper)
Spring 调用:new SysPostServiceImpl(sysPostMapper)
再创建 SysPostController
它依赖 ISysPostService
Spring 已经有了 sysPostServiceImpl(类型兼容 ISysPostService)
Spring 调用:new SysPostController(sysPostServiceImpl)
从 Spring 4.3 开始,只要类只有一个构造函数,就自动用于依赖注入,无需注解。这是官方推荐做法