ContiNew Admin组件开发:可复用业务组件的设计与实现

ContiNew Admin组件开发:可复用业务组件的设计与实现

【免费下载链接】continew-admin 🔥Almost最佳后端规范🔥页面现代美观,且专注设计与代码细节的高质量多租户中后台管理系统框架。开箱即用,持续迭代优化,持续提供舒适的开发体验。当前采用技术栈:Spring Boot3(Java17)、Vue3 & Arco Design、TS、Vite5 、Sa-Token、MyBatis Plus、Redisson、FastExcel、CosId、JetCache、JustAuth、Crane4j、Spring Doc、Hutool 等。 AI 编程纪元,从 ContiNew & AI 开始优雅编码,让 AI 也“吃点好的”。 【免费下载链接】continew-admin 项目地址: https://gitcode.com/continew/continew-admin

引言:为什么需要可复用业务组件?

在企业级应用开发中,你是否经常遇到这样的场景:每个业务模块都需要实现相似的CRUD(Create, Read, Update, Delete)操作,重复编写相似的控制器、服务层代码,不仅效率低下,还容易产生代码冗余和不一致的问题?

ContiNew Admin通过精心设计的可复用业务组件架构,将通用业务逻辑抽象为可复用的基础组件,让开发者能够专注于业务核心逻辑,大幅提升开发效率和代码质量。本文将深入解析ContiNew Admin的可复用业务组件设计理念和实现细节。

组件架构设计概览

ContiNew Admin采用分层架构设计,通过基础组件、业务组件和扩展组件的组合,构建了一套完整的可复用组件体系。

mermaid

核心组件层次结构

组件层级核心类主要职责复用程度
基础层BaseController提供通用CRUD接口和权限校验
基础层BaseService定义通用业务接口契约
基础层BaseServiceImpl实现通用业务逻辑和数据填充
业务层具体Controller处理特定业务逻辑和自定义接口
业务层具体Service实现特定业务规则

基础控制器组件详解

BaseController:统一的请求处理入口

BaseController 是所有业务控制器的基类,它封装了通用的CRUD操作和权限校验逻辑:

public class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q, C> 
    extends AbstractCrudController<S, L, D, Q, C> {
    
    @Override
    public void preHandle(CrudApi crudApi, Object[] args, Method targetMethod, 
                         Class<?> targetClass) throws Exception {
        // 忽略带签名的请求权限校验
        SaRequest saRequest = SaHolder.getRequest();
        Collection<String> paramNames = saRequest.getParamNames();
        if (paramNames.stream().anyMatch(SaSignTemplate.sign::equals)) {
            return;
        }
        
        // 忽略带有@SaIgnore注解的接口
        if (AnnotationUtil.hasAnnotation(targetMethod, SaIgnore.class) || 
            AnnotationUtil.hasAnnotation(targetClass, SaIgnore.class)) {
            return;
        }
        
        // 权限校验逻辑
        String permissionPrefix = CrudApiPermissionPrefixCache.get(targetClass);
        String apiName = getApiName(crudApi.value());
        StpUtil.checkPermission("%s:%s".formatted(permissionPrefix, apiName.toLowerCase()));
    }
}

权限校验机制

ContiNew Admin采用基于Sa-Token的细粒度权限控制,通过统一的权限前缀缓存机制实现动态权限校验:

mermaid

基础服务组件设计

BaseService:统一的业务接口契约

BaseService 接口定义了通用的业务操作方法,采用泛型设计支持不同类型的实体和DTO:

public interface BaseService<L, D, Q, C> extends CrudService<L, D, Q, C> {
    // 根据实际项目需要,自行重写CRUD接口或增加自定义通用业务方法
}

BaseServiceImpl:通用的业务实现

BaseServiceImpl 提供了CRUD操作的默认实现,并集成了Crane4j数据自动填充功能:

public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseIdDO, L, D, Q, C> 
    extends CrudServiceImpl<M, T, L, D, Q, C> implements BaseService<L, D, Q, C> {

    @Override
    protected void fill(Object obj) {
        if (obj == null) {
            return;
        }
        OperateTemplate operateTemplate = SpringUtil.getBean(OperateTemplate.class);
        operateTemplate.execute(obj);
    }
}

实战:用户管理组件的实现

用户控制器组件

用户控制器继承自BaseController,在通用CRUD功能基础上增加了用户特有的业务方法:

@Tag(name = "用户管理 API")
@Validated
@RestController
@RequiredArgsConstructor
@CrudRequestMapping(value = "/system/user", api = {Api.PAGE, Api.LIST, Api.GET, 
    Api.CREATE, Api.UPDATE, Api.BATCH_DELETE, Api.EXPORT, Api.DICT})
public class UserController extends BaseController<UserService, UserResp, UserDetailResp, UserQuery, UserReq> {

    // 下载导入模板
    @SaCheckPermission("system:user:import")
    @GetMapping(value = "/import/template", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void downloadImportTemplate(HttpServletResponse response) throws IOException {
        baseService.downloadImportTemplate(response);
    }

    // 解析导入数据
    @SaCheckPermission("system:user:import")
    @PostMapping("/import/parse")
    public UserImportParseResp parseImport(@RequestPart @NotNull(message = "文件不能为空") MultipartFile file) {
        ValidationUtils.throwIf(file::isEmpty, "文件不能为空");
        return baseService.parseImport(file);
    }

    // 重置密码
    @SaCheckPermission("system:user:resetPwd")
    @PatchMapping("/{id}/password")
    public void resetPassword(@RequestBody @Valid UserPasswordResetReq req, @PathVariable Long id) {
        String newPassword = SecureUtils.decryptByRsa(req.getNewPassword(), "新密码解密失败", true);
        req.setNewPassword(newPassword);
        baseService.resetPassword(req, id);
    }
}

用户服务组件

用户服务接口继承自BaseService,定义了用户管理特有的业务方法:

public interface UserService extends BaseService<UserResp, UserDetailResp, UserQuery, UserReq>, 
    IService<UserDO> {
    
    void downloadImportTemplate(HttpServletResponse response) throws IOException;
    
    UserImportParseResp parseImport(MultipartFile file);
    
    UserImportResp importUser(UserImportReq req);
    
    void resetPassword(UserPasswordResetReq req, Long id);
    
    void updateRole(UserRoleUpdateReq updateReq, Long id);
}

组件复用模式分析

1. 继承复用模式

通过继承基础组件,快速获得通用功能:

// 部门控制器 - 只需简单配置即可获得完整CRUD功能
@CrudRequestMapping(value = "/system/dept", api = {Api.TREE, Api.GET, Api.CREATE, 
    Api.UPDATE, Api.DELETE, Api.EXPORT, Api.DICT_TREE})
public class DeptController extends BaseController<DeptService, DeptResp, DeptDetailResp, DeptQuery, DeptReq> {
    // 无需额外代码即可获得完整的部门管理功能
}

2. 组合复用模式

通过服务组合实现复杂业务逻辑:

mermaid

3. 配置驱动模式

通过注解配置实现功能定制:

@CrudRequestMapping(value = "/system/user", 
    api = {Api.PAGE, Api.LIST, Api.GET, Api.CREATE, 
           Api.UPDATE, Api.BATCH_DELETE, Api.EXPORT, Api.DICT})

支持的功能配置选项:

配置选项说明示例值
value接口路径前缀"/system/user"
api开放的API类型{Api.PAGE, Api.LIST, Api.GET}
permission权限前缀"system:user"

高级特性:数据自动填充

ContiNew Admin集成Crane4j框架,实现了数据自动填充功能,显著减少联表查询:

public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseIdDO, L, D, Q, C> 
    extends CrudServiceImpl<M, T, L, D, Q, C> {

    @Override
    protected void fill(Object obj) {
        if (obj == null) {
            return;
        }
        OperateTemplate operateTemplate = SpringUtil.getBean(OperateTemplate.class);
        operateTemplate.execute(obj);
    }
}

数据填充流程:

mermaid

最佳实践:组件开发指南

1. 控制器开发规范

// ✅ 正确示例:遵循统一的控制器结构
@Tag(name = "部门管理 API")
@RestController
@CrudRequestMapping(value = "/system/dept", api = {Api.TREE, Api.GET, Api.CREATE, 
    Api.UPDATE, Api.DELETE, Api.EXPORT, Api.DICT_TREE})
public class DeptController extends BaseController<DeptService, DeptResp, DeptDetailResp, DeptQuery, DeptReq> {
    
    // 自定义接口需要明确权限注解
    @SaCheckPermission("system:dept:customOperation")
    @PostMapping("/custom-operation")
    public void customOperation() {
        // 业务逻辑
    }
}

2. 服务层开发规范

// ✅ 正确示例:服务接口继承BaseService
public interface DeptService extends BaseService<DeptResp, DeptDetailResp, DeptQuery, DeptReq>, 
    IService<DeptDO> {
    
    // 自定义业务方法
    void customBusinessMethod(CustomReq req);
}

// ✅ 正确示例:服务实现继承BaseServiceImpl
public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptResp, DeptDetailResp, DeptQuery, DeptReq> 
    implements DeptService {
    
    @Override
    public void customBusinessMethod(CustomReq req) {
        // 业务实现
    }
}

3. 异常处理规范

ContiNew Admin提供了统一的异常处理机制,组件开发时应遵循:

  • 业务异常使用ServiceException抛出
  • 参数校验异常使用Jakarta Validation注解
  • 权限异常由Sa-Token统一处理

性能优化策略

1. 缓存策略优化

// 使用JetCache注解实现方法级缓存
@Cached(name = "user:", key = "#id", expire = 300)
@Override
public UserDetailResp get(Long id) {
    return super.get(id);
}

2. 批量操作优化

// 批量操作减少数据库交互
@Transactional(rollbackFor = Exception.class)
@Override
public void delete(List<Long> ids) {
    // 先执行业务逻辑校验
    validateBeforeDelete(ids);
    // 调用父类批量删除方法
    super.delete(ids);
}

3. 数据查询优化

// 使用MyBatis Plus的Lambda查询优化
@Override
protected Wrapper<T> buildQueryWrapper(Q query) {
    return Wrappers.<T>lambdaQuery()
        .eq(ObjectUtils.isNotEmpty(query.getStatus()), T::getStatus, query.getStatus())
        .like(ObjectUtils.isNotEmpty(query.getKeyword()), T::getKeyword, query.getKeyword())
        .orderByDesc(T::getCreateTime);
}

组件测试策略

1. 单元测试覆盖

@ExtendWith(MockitoExtension.class)
class UserControllerTest {
    
    @Mock
    private UserService userService;
    
    @InjectMocks
    private UserController userController;
    
    @Test
    void shouldResetPasswordSuccessfully() {
        // 测试数据准备
        UserPasswordResetReq req = new UserPasswordResetReq();
        Long userId = 1L;
        
        // 执行测试
        userController.resetPassword(req, userId);
        
        // 验证结果
        verify(userService).resetPassword(any(), eq(userId));
    }
}

2. 集成测试方案

@SpringBootTest
@AutoConfigureMockMvc
class UserControllerIntegrationTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @Test
    void shouldReturnUserList() throws Exception {
        mockMvc.perform(get("/system/user/list")
                .header("Authorization", "Bearer token"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data").isArray());
    }
}

总结与展望

ContiNew Admin的可复用业务组件架构通过以下设计实现了高效的组件复用:

  1. 统一的基类设计BaseControllerBaseService提供了通用的CRUD功能和权限校验
  2. 灵活的配置机制:通过注解配置实现功能定制,满足不同业务场景需求
  3. 数据自动填充:集成Crane4j框架,减少联表查询,提升性能
  4. 完善的异常处理:统一的异常处理机制,保证系统稳定性

未来,ContiNew Admin将继续优化组件架构,计划在以下方面进行改进:

  • 支持更灵活的插件化组件机制
  • 增强组件的可观测性,提供更详细的运行指标
  • 优化组件间的通信机制,提升系统性能
  • 提供更多的预制业务组件,进一步降低开发成本

通过可复用业务组件的设计和实现,ContiNew Admin为开发者提供了一套高效、稳定、易扩展的开发框架,让企业级应用开发变得更加简单和高效。

【免费下载链接】continew-admin 🔥Almost最佳后端规范🔥页面现代美观,且专注设计与代码细节的高质量多租户中后台管理系统框架。开箱即用,持续迭代优化,持续提供舒适的开发体验。当前采用技术栈:Spring Boot3(Java17)、Vue3 & Arco Design、TS、Vite5 、Sa-Token、MyBatis Plus、Redisson、FastExcel、CosId、JetCache、JustAuth、Crane4j、Spring Doc、Hutool 等。 AI 编程纪元,从 ContiNew & AI 开始优雅编码,让 AI 也“吃点好的”。 【免费下载链接】continew-admin 项目地址: https://gitcode.com/continew/continew-admin

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值