• springboot~为ES实体封装审计Auditing功能


    审记功能在Jpa框架里出现的,主要针对实体的几个字段进行自动化的赋值,让业务人员可以把关注点放在业务上,对于公用的,有规则的字段,由系统帮我们去处理。

    原理

    通过spring aop功能实现对es仓库接口方法的拦截,然后在方法处理之前,为实体的这些公用字段赋值即可,我们使用了jpa里的一些注解,如@CreateBy,@CreateDate,@LatestModifyDate等等。

    EsBaseEntity实体

    
    @Data
    public class EsBaseEntity {
    
        public static final String dateTimeFormat = "yyyy/MM/dd||yyyy-MM-dd" +
                "||yyyy-MM-dd HH:mm:ss||yyyy/MM/dd HH:mm:ss" +
                "||yyyy-MM-dd HH:mm:ss.SSS||yyyy/MM/dd HH:mm:ss.SSS" +
                "||yyyy-MM-dd'T'HH:mm:ss.SSS";
        /**
         * 创建时间.
         */
        @Field(type = FieldType.Date, format = DateFormat.custom, pattern = dateTimeFormat)
        @CreatedDate
        protected String createTime;
        /**
         * 创建人.
         */
        @Field(type = FieldType.Keyword)
        @CreatedBy
        protected String creator;
        /**
         * 更新时间.
         */
        @Field(type = FieldType.Date, format = DateFormat.custom, pattern = dateTimeFormat)
        @LastModifiedDate
        protected String updateTime;
        /**
         * 更新人.
         */
        @Field(type = FieldType.Keyword)
        @LastModifiedBy
        protected String updateUser;
        /**
         * 删除标记.
         */
        @Field(type = FieldType.Keyword)
        protected boolean delFlag;
        /**
         * 主键.
         */
        @Id
        private String id = String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
    
    }
    
    

    审记拦截器

    @Component
    @Aspect
    public class AuditAspect {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
        /**
         * 添加ES实体-切入点
         */
        @Pointcut("execution(* org.springframework.data.repository.CrudRepository.save(..))")
        public void save() {
        }
    
        /**
         * 更新ES实体-切入点
         */
        @Pointcut("execution(* org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.update(..))")
        public void update() {
        }
    
        /**
         * 插入实体拦截器.
         *
         * @param joinPoint
         * @throws IllegalAccessException
         */
        @Before("save()")
        public void beforeSave(JoinPoint joinPoint) throws IllegalAccessException {
            System.out.println("插入拦截");
    
            if (joinPoint.getArgs().length > 0) {
                Object esBaseEntity = joinPoint.getArgs()[0];
                Field[] fields = ClassHelper.getAllFields(esBaseEntity.getClass());
                List<Field> fieldList = Arrays.stream(fields)
                        .filter(o -> o.getAnnotation(CreatedDate.class) != null
                                || o.getAnnotation(LastModifiedDate.class) != null)
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(fieldList)) {
                    for (Field field : fieldList) {
                        field.setAccessible(true);//取消私有字段限制
                        if (field.get(esBaseEntity) == null) {
                            field.set(esBaseEntity, df.format(new Date()));
                        }
                    }
                }
                List<Field> auditFieldList = Arrays.stream(fields)
                        .filter(o -> o.getAnnotation(CreatedBy.class) != null
                                || o.getAnnotation(LastModifiedBy.class) != null)
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(auditFieldList)) {
                    for (Field field : auditFieldList) {
                        field.setAccessible(true);//取消私有字段限制
                        if (field.get(esBaseEntity) == null) {
                            EsAuditorAware esAuditorAware = SpringContextConfig.getBean(EsAuditorAware.class);
                            if (esAuditorAware != null) {
                                field.set(esBaseEntity, esAuditorAware.getCurrentAuditor().orElse(null));
                            }
                        }
                    }
                }
            }
    
        }
    
        /**
         * 更新实体拦截器.
         *
         * @param joinPoint
         */
        @Before("update()")
        public void beforeUpdate(JoinPoint joinPoint) {
            System.out.println("更新拦截");
            if (joinPoint.getArgs().length == 1 && joinPoint.getArgs()[0] instanceof UpdateQuery) {
                UpdateQuery updateQuery = (UpdateQuery) joinPoint.getArgs()[0];
                Map source = updateQuery.getUpdateRequest().doc().sourceAsMap();
                Field[] fields = ClassHelper.getAllFields(updateQuery.getClazz());
                List<Field> fieldList = Arrays.stream(fields)
                        .filter(o -> o.getAnnotation(LastModifiedDate.class) != null)
                        .collect(Collectors.toList());
                for (Field field : fieldList) {
                    if (!source.containsKey(field.getName())) {
                        source.put(field.getName(), df.format(new Date()));
                    }
                }
                List<Field> auditFieldList = Arrays.stream(fields)
                        .filter(o -> o.getAnnotation(LastModifiedBy.class) != null)
                        .collect(Collectors.toList());
                for (Field field : auditFieldList) {
                    if (!source.containsKey(field.getName())) {
                        EsAuditorAware esAuditorAware = SpringContextConfig.getBean(EsAuditorAware.class);
                        if (esAuditorAware != null) {
                            source.put(field.getName(), esAuditorAware.getCurrentAuditor().orElse(null));
                        }
                    }
                }
                updateQuery.getUpdateRequest().doc().source(source);
            }
        }
    }
    
    

    对审记人使用Aware方式实现

    /**
     * Es获取审核当前对象.
     *
     * @param <T>
     */
    public interface EsAuditorAware<T> {
        Optional<T> getCurrentAuditor();
    }
    /**
     * 得到当前操作人信息.
     */
    @Component
    public class UserAuditorAware implements EsAuditorAware<String> {
        @Override
        public Optional<String> getCurrentAuditor() {
            return Optional.of("1");
        }
    }
    
    

    第三方组件开启审计功能

    /**
     * 开启ES审计功能.
     * 主要对建立人、建立时间、更新人、更新时间赋值.
     */
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({AuditAspect.class, SpringContextConfig.class})
    public @interface EnableEsAuditing {
    }
    
    
  • 相关阅读:
    SCOPE_IDENTITY和@@identity的区别
    IE6.0、IE7.0 与FireFox CSS兼容的解决方法
    DivCSS布局基础:CSS中控制换行的四种属性
    load的用法(问题未解决)
    设置每个li的margin距离(巧设计)
    IE6下设置float和margin的问题
    在IE7下设置zindex没有反应
    做css页面时,注意的地方
    专题页
    IE8下margintop问题
  • 原文地址:https://www.cnblogs.com/lori/p/13442919.html
Copyright © 2020-2023  润新知