最近做的都是迁移工作,纯粹的CV大法,不值一提。
看了书和文章,总结不起来,还是差一些东西。
我发现还是要多写代码,多实践。这样才能把从别人那看到的、学到的拿来成为自己的。
今天依然是CV大法,但是我发现一天Controller类里,所有的接口都有一段共同的,例如根据设备Id验证设备是否存在。
献丑一下我仅有的知识,这是不是可以来个切面或者说来个拦截器,最开始想的是根据请求路径拦截,只要是指定路径的都要先走一遍验证。这个想法没有尝试。
我采用了切面,切入点为自定义通知。
简单介绍一下实现思路
1. 在需要验证设备的方法上,添加自定义注解
2. 自定义切面类,说白了就是增加@Aspect+@Component注解,交由spring来管理
3. 定义切入点,比如是在哪个类的哪些方法,或者有指定注解的地方切入
4. 定义切入的时刻,我的需求是在目标方法之前执行,所以用的@Before
具体代码如下:
@Slf4j
@Aspect
@Component
public class ValidDeviceBeforeMapAspect {
public IWebDeviceService webDeviceService = SpringUtils.getBean(IWebDeviceService.class);
/**
* 构建
*/
public ValidDeviceBeforeMapAspect() {
log.info(" construct ......ValidDeviceBeforeMapAspect..........");
}
/**
* 声明AOP签名
*/
@Pointcut(value = "@annotation(com.bdht.system.map.aspect.DeviceValidated)")
public void pointcut() {
}
@Before(value = "pointcut()")
public void doBefore(JoinPoint joinPoint) {
checkDevice(joinPoint);
}
private void checkDevice(JoinPoint joinPoint) {
long deviceId = 0L;
for (Object arg : joinPoint.getArgs()) {
Class thisClass = arg.getClass();
try {
Field deviceIdField = thisClass.getField("deviceId");
deviceId = Objects.nonNull(deviceIdField) ? (Long)deviceIdField.get(arg) : 0L;
} catch (Exception e) {
e.printStackTrace();
}
}
DeviceEntity deviceEntity = webDeviceService.getDeviceEntityById(deviceId);
if(Objects.isNull(deviceEntity)) throw new ServiceException("设备ID填写有误");
}
在需要验证设备的接口,增加注解:@DeviceValidated
经过测试,功能是没问题的。
get到的点:
1. @Before通知,是通过JoinPoint去获取请求参数及类
2. ProceedingJoinPoint,是环绕通知专属
无数的CV,今天终于有一点小开心,因为把学到的知识用到了项目里,💪💪💪