美文网首页
注解aop实战

注解aop实战

作者: 快点给我想个名 | 来源:发表于2020-06-08 19:02 被阅读0次

    场景

    在一数据库里有几张表,需要在触发字段更新的时候记录下来操作人和更新字段前后的值。不依赖MQ和监听binlog,直接自定义注解,基于AOP功能实现。最简单版本

    实现

    • 定义注解
    @Target({ METHOD })
    @Retention(RUNTIME)
    public @interface RecordUpdate {
    
        /**
         * 对应表名
         * @return
         */
        String tableName();
    
        /**
         * 处理类
         * @return
         */
        Class<? extends UpdateAspectHandler> handler();
    
        /**
         * 表对应实体参数位置
         * @return
         */
        int tableEntityIndex();
    
        /**
         * 操作人ID参数位置
         * @return
         */
        int operatorIdIndex();
        /**
         * 操作人类型参数位置
         * @return
         */
        int operatorTypeIndex();
    }
    
    • 定义切面
    @Aspect
    @Component
    public abstract class UpdateAspectHandler implements ApplicationContextAware {
    
        private static Logger logger = LoggerFactory.getLogger(UpdateAspectHandler.class);
    
        private ApplicationContext applicationContext;
    
    
        @Before(value = "execution(public * com.simon.dataplatform..*(..)) && @annotation(com.simon.dataplatform.userprofile.annotation.RecordUpdate)")
        public void before(JoinPoint joinPoint) throws NoSuchMethodException {
    
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            // 获取方法
            Method method = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes());
            // 获取参数
            Object[] args = joinPoint.getArgs();
            // 获取注解
            RecordUpdate recordUpdate = method.getAnnotation(RecordUpdate.class);
            if(ObjectUtil.isNull(recordUpdate)) {
                return;
            }
    
            // 获取参数
            String tableName = recordUpdate.tableName();
            Object operatorId = args[recordUpdate.operatorIdIndex()];
            Object operatorType = args[recordUpdate.operatorTypeIndex()];
            Object tableEntity = args[recordUpdate.tableEntityIndex()];
    
            try {
                // 获取处理类代理对象
                UpdateAspectHandler updateAspectHandler = applicationContext.getBean(recordUpdate.handler());
                updateAspectHandler.processBefore(tableName,tableEntity,operatorId,operatorType);
            } catch (Exception e) {
                logger.info("UpdateAspectHandler.before tableName:{},operatorId:{},operatorType:{},tableEntity:{}",tableEntity,operatorId,operatorType, JSON.toJSON(tableEntity));
                logger.error("UpdateAspectHandler.before error:{}",e);
            }
        }
    
        /**
         * 交由具体实现类处理
         * @param tableName 表名
         * @param tableEntity 表对应实体
         * @param operatorId 操作人ID
         * @param operatorType 操作人类型
         */
        public abstract void processBefore(String tableName,Object tableEntity, Object operatorId, Object operatorType);
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
        }
    }
    
    • 定义UserBaseExt表对应的处理类
    @Component
    public class UserBaseExtAspectHandler extends UpdateAspectHandler {
    
        @Resource(name = "userBaseExtService")
        private UserBaseExtService userBaseExtService;
    
        @Resource(name = "userUpdateLogService")
        private UserUpdateLogService userUpdateLogService;
        
         /**
         * 忽略的属性字段
         */
        private List<String> ignoreFieldList = Arrays.asList("id,update_time,add_time".split(","));
        
    
        @Override
        public void processBefore(String tableName, Object tableEntity, Object operatorId, Object operatorType) {
            UserBaseExt afterUserBaseExt = (UserBaseExt) tableEntity;
    
            UserBaseExt beforeUserBaseExt = userBaseExtService.findByStuId(afterUserBaseExt.getStuId());
            if(ObjectUtil.isNull(beforeUserBaseExt)) {
                return;
            }
    
            Date date = new Date();
            Field[] fields = ReflectUtil.getFields(UserBaseExt.class);
            List<UserUpdateLog> userUpdateLogList = new ArrayList<>(fields.length);
            for (Field field : fields) {
                // 驼峰转蛇形工具类:实体userName,数据库user_name
                String fieldName = ConvFieldNameUtil.camelToUnderline(field.getName());
                
                if(ignoreFieldList.contains(fieldName) || Modifier.isStatic(field.getModifiers())){
                    continue;
                }
    
                Object afterValue = ReflectUtil.getFieldValue(afterUserBaseExt, field);
                // null值底层不更新
                Object afterValue = ReflectUtil.getFieldValue(after, field);
                if(ObjectUtil.isNull(afterValue)){
                    continue;
                }
                
                Object beforeValue = ReflectUtil.getFieldValue(beforeUserBaseExt,field);
    
                if(!ObjectUtil.equal(afterValue,beforeValue)) {
                    UserUpdateLog userUpdateLog = new UserUpdateLog();
                    userUpdateLog.setStuId(afterUserBaseExt.getStuId());
                    userUpdateLog.setOperatorId(Long.valueOf(String.valueOf(operatorId)));
                    userUpdateLog.setOperatorType(String.valueOf(operatorType));
                    userUpdateLog.setTableName(tableName);
                    userUpdateLog.setUpdateTime(date);
                    userUpdateLog.setFieldName(field.getName());
                    // 对于过长字符串进行截取
                    userUpdateLog.setBeforeValue(StrUtil.sub(beforeValue+"",0,128));
                    userUpdateLog.setAfterValue(StrUtil.sub(afterValue+"",0,128));
                    userUpdateLogList.add(userUpdateLog);
                }
            }
            if(CollectionUtil.isNotEmpty(userUpdateLogList)) {
                userUpdateLogService.insertBatch(userUpdateLogList);
            }
        }
    }
    
    • 使用
    @Override
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    @RecordUpdate(tableName = "user_base_ext",handler = UserBaseExtAspectHandler.class,tableEntityIndex = 0,operatorIdIndex = 1,operatorTypeIndex = 2)
    public void updateByStuId(UserBaseExt userBaseExt,Long operatorId,String operatorType) {
        userBaseExt.setUpdateTime(new Date());
        userBaseExtDao.updateByStuId(userBaseExt);
    }
    

    相关文章

      网友评论

          本文标题:注解aop实战

          本文链接:https://www.haomeiwen.com/subject/mzynzhtx.html