以下是一个基于Java项目分层架构实操指南等最新技术的Java项目分层架构实操指南,结合用户管理系统实例进行说明。
采用微服务架构,使用Spring Cloud套件实现服务治理,整体分层结构如下:
user-service/ # 用户服务微服务
├── src/main/java/com/example
│ ├── controller/ # Web层(控制器)
│ ├── service/ # Service层(业务逻辑)
│ │ ├── impl/ # Service实现
│ ├── manager/ # Manager层(通用业务处理)
│ ├── mapper/ # Mapper层(数据访问)
│ ├── entity/ # 实体层
│ ├── dto/ # 数据传输对象
│ ├── vo/ # 视图对象
│ ├── config/ # 配置层
│ ├── utils/ # 工具层
│ └── UserServiceApplication.java # 启动类
└── src/main/resources
├── mapper/ # MyBatis映射文件
├── application.yml # 配置文件
使用Lombok简化POJO开发,添加JPA注解支持。
// User.java
@Data
@TableName("sys_user")
@EqualsAndHashCode(callSuper = false)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
private Long id;
@NotBlank(message = "用户名不能为空")
private String username;
@JsonIgnore // 避免密码暴露
private String password;
private String email;
@TableField(fill = FieldFill.INSERT) // 自动填充创建时间
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE) // 自动填充更新时间
private LocalDateTime updateTime;
}
继承MyBatis-Plus的BaseMapper
接口,无需编写基础CRUD方法。
// UserMapper.java
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 自定义复杂查询方法
@Select("SELECT * FROM sys_user WHERE username = #{username}")
User selectByUsername(@Param("username") String username);
}
使用事务管理和缓存优化,调用Manager层处理通用逻辑。
// UserService.java
public interface UserService extends IService<User> {
Result<Boolean> register(UserDTO userDTO);
Result<UserVO> login(LoginDTO loginDTO);
}
// UserServiceImpl.java
@Service
@Transactional
@RequiredArgsConstructor // Lombok生成构造器注入
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
private final RedisManager redisManager;
private final PasswordEncoder passwordEncoder;
private final JwtManager jwtManager;
@Override
public Result<Boolean> register(UserDTO userDTO) {
// 1. 校验用户名唯一性(调用Manager层)
if (userMapper.selectByUsername(userDTO.getUsername()) != null) {
return Result.fail("用户名已存在");
}
// 2. 密码加密
User user = BeanUtil.copyProperties(userDTO, User.class);
user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
// 3. 保存用户
boolean success = save(user);
// 4. 注册成功后缓存用户信息
if (success) {
redisManager.setCacheObject(CacheConstants.USER_KEY + user.getId(), user);
}
return Result.ok(success);
}
@Override
public Result<UserVO> login(LoginDTO loginDTO) {
// 1. 查询用户
User user = userMapper.selectByUsername(loginDTO.getUsername());
// 2. 校验密码
if (user == null || !passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
return Result.fail("用户名或密码错误");
}
// 3. 生成JWT令牌
String token = jwtManager.generateToken(user.getId().toString());
// 4. 构建返回VO
UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
userVO.setToken(token);
return Result.ok(userVO);
}
}
封装第三方服务和通用操作,如缓存、消息队列等。
// RedisManager.java
@Component
@RequiredArgsConstructor
public class RedisManager {
private final RedisTemplate<String, Object> redisTemplate;
public <T> void setCacheObject(String key, T value) {
redisTemplate.opsForValue().set(key, value);
}
public <T> T getCacheObject(String key) {
ValueOperations<String, Object> operations = redisTemplate.opsForValue();
return (T) operations.get(key);
}
public Boolean deleteObject(String key) {
return redisTemplate.delete(key);
}
}
// JwtManager.java
@Component
@RequiredArgsConstructor
public class JwtManager {
private static final String SECRET_KEY = "your-secret-key";
private static final long EXPIRATION_TIME = 86400000; // 24小时
public String generateToken(String userId) {
return Jwts.builder()
.setSubject(userId)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public String getUserIdFromToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
}
处理HTTP请求,校验参数,返回统一格式结果。
// UserController.java
@RestController
@RequestMapping("/api/users")
@Api(tags = "用户管理")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping("/register")
@ApiOperation("用户注册")
public Result<Boolean> register(@RequestBody @Valid UserDTO userDTO) {
return userService.register(userDTO);
}
@PostMapping("/login")
@ApiOperation("用户登录")
public Result<UserVO> login(@RequestBody @Valid LoginDTO loginDTO) {
return userService.login(loginDTO);
}
@GetMapping("/{id}")
@ApiOperation("获取用户详情")
@PreAuthorize("hasAuthority('user:view')") // 权限校验
public Result<UserVO> getUser(@PathVariable Long id) {
User user = userService.getById(id);
return Result.ok(BeanUtil.copyProperties(user, UserVO.class));
}
}
// Result.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {
private Integer code;
private String message;
private T data;
public static <T> Result<T> ok(T data) {
return new Result<>(200, "操作成功", data);
}
public static <T> Result<T> fail(String message) {
return new Result<>(500, message, null);
}
}
// MyBatisPlusConfig.java
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
// MyMetaObjectHandler.java
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
}
}
// EurekaServerApplication.java
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
# application.yml
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service # 服务名
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1 # 去除路径前缀
sys_user
表,添加必要字段。// 注册请求示例
POST http://localhost:8080/api/users/register
{
"username": "test",
"password": "123456",
"email": "test@example.com"
}
// 登录请求示例
POST http://localhost:8080/api/users/login
{
"username": "test",
"password": "123456"
}
通过这个实操案例,你可以看到现代Java项目分层架构的最佳实践:
建议在实际项目中根据需求调整架构,不需要完全遵循所有层次,保持"够用就好"的原则。
Java 项目分层架构,Spring Boot, 微服务架构,分层设计原则,后端开发,架构案例解析,领域驱动设计,持久层设计,服务层架构,控制层实现,分层架构最佳实践,企业级应用架构,模块化开发,架构优化,Java 架构实战
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。