开发指南143-扩展类功能

客户业务唯一不变的是总在变。

客户和客户之间有80%是一样的,只有20%的不同。应对这20%,如果在源代码里改,会带来一个显著的问题:动过的部分和原始不一了,原始部分无非升级了。

比较好的方式是这80%封装为产品层,可以独立升级。其他20%通过扩展机制实现。这个扩展机制不要动产品层的代码。

完成这个机制的核心就是切片编程中@Around。@Around有很多用法,只掌握一招就足够,那就是execution。

假设产品的功能函数在org.qlm.mdm包下,类名为hrServiceImpl,函数为addPerson。

@Aspect // 声明为切面类

@Component // 交给 Spring 容器管理

public class HRAspect {

@Around("execution(* org.qlm.mdm.hrServiceImpl.addPerson(..))")

public Object aroundUserInfo(ProceedingJoinPoint joinPoint) throws Throwable {

// 1. 目标方法执行前的逻辑

System.out.println("目标方法调用前,获取参数:" + joinPoint.getArgs()0);

long startTime = System.currentTimeMillis();

Object result = null;

try {

// 2. 执行目标方法(核心步骤,决定是否调用目标方法)

result = joinPoint.proceed();

// 3. 目标方法执行后的逻辑(无异常时)

long endTime = System.currentTimeMillis();

System.out.println("目标方法执行完成,耗时:" + (endTime - startTime) + "ms,返回结果:" + result);

} catch (Throwable e) {

// 4. 目标方法抛出异常时的逻辑

System.out.println("目标方法执行出错:" + e.getMessage());

throw e; // 可选:抛出异常,让上层感知

}

return result; // 返回目标方法的结果(可修改)

}

}

这样就在不动原始代码,甚至不需要原始代码的情况下扩展了功能(例如只有jar包)。但是有如下先决条件:

1、工程里需要有如下依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

2、被增强的 hrServiceImpl必须是 Spring 容器中的 Bean(即添加 @Service/@Component 等注解),不能手动 new 实例。

3、切面类和目标类必须在 Spring 扫描范围内。

相关推荐
2601_961194023 分钟前
考研资料电子版|去哪找|网盘
java·c语言·c++·python·考研·php
于先生吖6 分钟前
前后端分离二手商城开发,质检登记、回收回款整套业务源码部署教程
java·开发语言·uni-app
codeejun9 分钟前
每日一Go-76(架构篇)|多集群部署 / 容灾 / Failover / Backup / 热迁移
开发语言·架构·golang
战族狼魂9 分钟前
从零构建企业级Hermes-Agent:复杂任务拆解、工具协同与安全落地实践
开发语言·人工智能·python
小锋java123425 分钟前
分享一套锋哥原创的基于LangChain4j的RAG医疗健康知识智能问答系统(SpringBoot4+Vue3+Ollama)
java·人工智能
阿里嘎多学长31 分钟前
2026-06-08 GitHub 热点项目精选
开发语言·程序员·github·代码托管
程序员晨曦44 分钟前
Java 并发修仙传:ThreadLocal 从“闭关修炼”到“走火入魔”的救赎之路
java·开发语言
AIGS0011 小时前
探索向量空间JBoltAI:工业企业数智化升级的基础设施
java·人工智能·人工智能ai大模型应用
李可以量化1 小时前
量化之MiniQMT 实战:一键读取通达信自选股并实时监控涨跌幅(附完整可运行代码)
开发语言·python·量化·qmt·ptrade
嘶哈哈哈1 小时前
嘉立创 EDA 入门实操笔记:从原理图到 PCB 布线、差分对、覆铜与 DRC 检查
开发语言·笔记·php