SpringAop实现公共字段数据填充
背景
由于我们系统的很多表都用到了一些公共的字段,所以就考虑将这些公共字段抽离出来做一个基础的公共类,便于维护和减少代码量
实现
原理
原理其实很简单,就是讲抽离的字段集成到一个实体类,然后再contoller层写一个自定义注解,再使用springboot的切面功能,再进入方法之前为我们的实体set基类里面的值
1. 基础实体类
将抽离的字段写一个公共基础类,目前处于业务需求考虑,暂时就只有 firsttime,lasttime,operator,operatorId
这四个字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
@Data public class BaseEntity {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date firsttime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date lasttime;
private String operator;
private String operatorId; }
|
2. 开启AOP切面
- 先引入maven配置
1 2 3 4 5
| <!-- aop --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
|
- 在配置文件处添加开启AOP的配置
1 2 3
| spring: aop: auto: true
|
3. 写一个自定义注解 AutoFillBaseEntity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AutoFillBaseEntity {
boolean setFirsttime() default true;
boolean setLasttime() default true;
boolean setOperator() default true;
boolean setOperatorId() default true; }
|
4. 写一个切面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
@Slf4j @Component @Aspect public class AutoFillBaseAspect {
@Pointcut("@annotation(cn.com.cninfo.ace.web.manage.annotation.AutoFillBaseEntity)") public void pointcut() {
}
@Around("pointcut()") public void Around(ProceedingJoinPoint pj) throws Throwable { MethodSignature signature = (MethodSignature) pj.getSignature(); AutoFillBaseEntity annotation = signature.getMethod().getAnnotation(AutoFillBaseEntity.class); if (annotation == null) { pj.proceed(); } Object[] args = pj.getArgs(); if (args == null) { pj.proceed(); } for (Object arg : args) { if (arg instanceof BaseEntity) { BaseEntity entity = (BaseEntity) arg; if (annotation.setFirsttime()) { entity.setFirsttime(new Date()); } if (annotation.setLasttime()) { entity.setLasttime(new Date()); } if (annotation.setOperator()) { entity.setOperator("操作用户"); } if (annotation.setOperatorId()) { entity.setOperatorId("操作用户ID"); } } } pj.proceed(); } }
|
使用方法
使用说明
该基类的使用主要是可以减少我们去写setLasttime,和setFirsttime 等操作,不使用一样是没问题的
1. 对我们需要的实体集成公共基础实体类
1 2 3 4 5 6 7 8 9 10
|
@Data public class SysFileDto extends BaseEntity implements Serializable { }
|
2. 在需要controller方法上加入我们的自定义注解
1 2 3 4 5 6 7 8 9 10 11
|
@PostMapping("update") @AutoFillBaseEntity(setFirsttime = false) public SysVariableDto update(@Validated @RequestBody SysVariableVo sysVariableVo){ return sysVariableService.update(sysVariableVo); }
|