最近做的都是迁移工作,纯粹的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,今天终于有一点小开心,因为把学到的知识用到了项目里,💪💪💪