自定义注解
1. 自定义一个注解类
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BpmInstanceLog {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
String group() default "";
OpType opType() default OpType.QUERY;
String description() default "";
String dataIdName() default "";
String instId() default "";
String key() default "";
}
2. 编写切面类,获取对应参数
@Aspect
@Component
public class BpmInstanceLogAnnotationAspect {
@Around("@annotation(bpmInstanceLog)")
public Object around(ProceedingJoinPoint point, BpmInstanceLog bpmInstanceLog) throws Throwable {
HttpServletRequest request = WebUtil.getRequest();
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("logGroup", bpmInstanceLog.group());
dataMap.put("logName", StringUtils.isBlank(bpmInstanceLog.name()) ? bpmInstanceLog.value() : bpmInstanceLog.name());
dataMap.put("opType", bpmInstanceLog.opType().name());
dataMap.put("description", bpmInstanceLog.description());
dataMap.put("path", Objects.requireNonNull(request).getRequestURI());
dataMap.put("opUserIp", ServletUtil.getClientIP(request));
String dataIdName = bpmInstanceLog.dataIdName();
String dataId = this.getDataId(point, dataIdName).toString();
if (StringUtils.isNotBlank(dataIdName)) {
dataMap.put("dataId", dataId);
}
String key = bpmInstanceLog.key();
if (StringUtils.isNotBlank(key)) {
dataMap.put("key", this.getDataKeyAndInstId(point, key));
}
String instId = bpmInstanceLog.instId();
if (StringUtils.isNotBlank(instId)) {
Object dataInstId = this.getDataKeyAndInstId(point, instId);
if (ObjectUtil.isNull(dataInstId)){
dataInstId = this.getDataId(point, instId);
if (ObjectUtil.isNull(dataInstId)){
dataInstId = dataId;
}
}
dataMap.put("instId", dataInstId);
}
SpringUtil.publishEvent(new BpmInstanceLogEvent(dataMap));
return point.proceed();
}
private Object getDataKeyAndInstId(ProceedingJoinPoint point, String dataName) throws Exception{
Object[] args = point.getArgs();
if (args.length == 1) {
Object value = args[0];
Map<String, Object> argsMap = this.obj2Map(value);
if (argsMap.containsKey(dataName)) {
return argsMap.get(dataName);
}
}
return null;
}
public Map<String,Object> obj2Map(Object obj) throws Exception{
Map<String,Object> map=new HashMap<>();
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
if (key.compareToIgnoreCase("class") == 0) {
continue;
}
Method getter = property.getReadMethod();
Object value = getter!=null ? getter.invoke(obj) : null;
map.put(key, value);
}
return map;
}
private Object getDataId(ProceedingJoinPoint point, String dataIdName) {
Object[] args = point.getArgs();
String[] names = ((CodeSignature) point.getSignature()).getParameterNames();
for (int i = 0; i < names.length; i++) {
if (dataIdName.equals(names[i])) {
Object dataId = args[i];
if (dataId != null && isPrimitiveWrapper(dataId.getClass())) {
return dataId;
}
return null;
}
}
for (Object arg : args) {
Class clazz = arg.getClass();
if (!isPrimitiveWrapper(clazz)) {
if (arg instanceof Map) {
Map map = (Map) arg;
return map.get(dataIdName);
} else {
try {
Field field = clazz.getDeclaredField(dataIdName);
field.setAccessible(true);
return field.get(arg);
} catch (Exception e) {
}
}
}
}
return null;
}
private boolean isPrimitiveWrapper(Class<?> calzz) {
return String.class.equals(calzz) || ClassUtil.isPrimitiveWrapper(calzz);
}
}
3. 编写日监听事件
public class BpmInstanceLogEvent extends ApplicationEvent {
public BpmInstanceLogEvent(Map<String, Object> source) {
super(source);
}
}
4. 实现监听
@Configuration
public class BpmInstanceLogListener {
@Resource
private Environment environment;
@Resource
private LogInstanceMapper logInstanceMapper;
@Async
@Order
@Transactional(rollbackFor = Exception.class)
@EventListener(BpmInstanceLogEvent.class)
public void saveLog(BpmInstanceLogEvent event) {
Map<String, Object> source = (Map<String, Object>) event.getSource();
LogInstance logInstance = BeanUtil.toBean(source, LogInstance.class);
logInstance.setLogId(String.valueOf(IdUtil.getId()));
logInstance.setOpUser(String.valueOf(AuthUtil.getUserId()));
logInstance.setOpDate(DateUtil.date().toTimestamp());
logInstance.setAppName(environment.getProperty("spring.application.name"));
logInstanceMapper.insert(logInstance);
}
}
5. 使用自定义注解@BpmInstanceLog
@PostMapping("/saveFormData")
@ApiOperation(value = "表单数据保存", notes = "表单数据保存")
@ApiOperationSupport(order = 13)
@BpmInstanceLog(name = "编辑表单", group = MODULE_SOLUTION, dataIdName = "dataId", instId = "instId", key = "key" ,opType = OpType.UPDATE)
public R<SaveFormDataResponse> saveFormData(@RequestBody BusinessSaveFormRequest formRequest) throws Exception {}