審記功能在Jpa框架裏出現的,主要針對實體的幾個字段進行自動化的賦值,讓業務人員能夠把關注點放在業務上,對於公用的,有規則的字段,由系統幫咱們去處理。spring
經過spring aop功能實現對es倉庫接口方法的攔截,而後在方法處理以前,爲實體的這些公用字段賦值便可,咱們使用了jpa裏的一些註解,如@CreateBy,@CreateDate,@LatestModifyDate等等。框架
@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); } } }
/** * 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 { }