1:第一次写博客,如果有问题请多多包含, 先说下思路: 1.1 :先建立一个注解类,这个是使用在方法上的。 1.2 :再建立一个专门做spring的bean的方法中传参解析的EL类。 1.3 : 这里我们还需要一个处理spring的AOP的类,针对注解做切面编程 , 这个类可以做公共日志打印 接下来就直接上代码了,下面的类是根据上面的思路来的。 1:注解类:用来放在方法前面,做切面使用 /** * 类描述: * 复核的判断验证 * @Author qq: 841495046 * @date: 2018/12/22 * @Version:1.1.0 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.METHOD}) public @interface VerificationMethod { /** * EL */ String entryKey(); /** * 方法名 * 多个方法请使用逗号隔开 * @return */ String method(); /** * 方法的描述 * @return */ String describe() default ""; /** * 是否需要日志打印 */ boolean needLog() default false; }
获取spring的EL的值: 通过spring来获取方法中入参的实体对象值
/** * 类描述: 获取spring的EL的值 * * @Author qq: 841495046 * @date: 2018/12/22 * @Version:1.1.0 */ public final class SpelEl { private static ExpressionParser parser = new SpelExpressionParser(); /** * @param key el表达式字符串,占位符以#开头 * @param paramsNames 形参名称,可以理解为占位符名称 * @param args 参数值,可以理解为占位符真实的值 * @功能描述: 返回el表达式经过参数替换后的字符串值 * @return: String * @Author qq: 841495046 * @date: 2018/12/22 10:09 * @Version:1.1.0 */ public static String getEntityKey(String key, String[] paramsNames, Object[] args) { Expression exp = parser.parseExpression(key); //初始化赋值上下文 EvaluationContext context = new StandardEvaluationContext(); if (args.length <= 0) { return null; } //将形参和形参值以配对的方式配置到赋值上下文中 for (int i = 0; i < args.length; i++) { context.setVariable(paramsNames[i], args[i]); } //根据赋值上下文运算el表达式 return exp.getValue(context, String.class); } /** * @param paramsNames : 形参名称,可以理解为占位符名称 * @功能描述: * @return: 获取对象 * @date: 2018/12/22 11:28 * @Version:1.1.0 */ public static Object getKeyEntity(String key, String[] paramsNames, Object[] args) { Expression exp = parser.parseExpression(key); EvaluationContext context = new StandardEvaluationContext(); if (args.length <= 0) { return null; } for (int i = 0; i < args.length; i++) { context.setVariable(paramsNames[i], args[i]); } return exp.getValue(context, Object.class); } }
3:spring的AOP处理类
@Component @Aspect public class MethodAspect { private static final Logger LOGGER = LoggerFactory.getLogger(MethodAspect.class); /** * @功能描述: Method method = ((MethodSignature)pjp.getSignature()).getMethod(); VerificationMethod * annotation = method.getAnnotation(VerificationMethod.class); * @return: Object * @date: 2018/12/22 11:21 * @Version:1.1.0 */ @Around("@annotation(vfm)") public Object doMethodValidate(ProceedingJoinPoint pjp, VerificationMethod vfm) throws Throwable { // 方法的入参 Object entryObject = getKeyEntity(pjp, vfm.entryKey()); String methodName = vfm.method(); String describe = vfm.describe(); boolean needLog = vfm.needLog(); OmPdaBoxDto omPdaBoxDto = null; if (needLog) { LOGGER.info("方法名[{}],方法描述[{}]", methodName, describe); } String[] methods = methodName.split(","); //有值 if (methods.length > 0) { omPdaBoxDto = BeanUtils.toBean(entryObject, OmPdaBoxDto.class); omPdaBoxDto.setLocno(OutputContext.getLocno()); omPdaBoxDto.setUserId(OutputContext.getCurrentSimpleUserInfo().getLoginName()); RecheckValidateMethod rvm = GetObjectBean.getRecheckValidateMethod(); int count = 1; for (String method : methods) { LOGGER.info("------------------转换方法:MethodAspect[{}]------------", method); ResultData<String> ob = (ResultData<String>) executionParameterMethod("validate" + method, rvm, new Object[]{omPdaBoxDto}); if (ob != null && ob.getCode() != 0) { return ob; } if (ob != null && count == 1 && StringUtils.isNotBlank(ob.getData())) { omPdaBoxDto.setDate(ob.getData()); } count++; if (ob != null && ob.getCode() == 0 && ob.getSubCode() != null) { return ob; } } } Object ret = null; try { ret = pjp.proceed(new Object[]{omPdaBoxDto}); } catch (Exception e) { LOGGER.error("MethodAspect方法异常" + describe + "[{}]", e.getMessage()); e.printStackTrace(); throw new BaseException("校验失败"); } return ret; } /** * @param pjp :注入对象 * @功能描述 : 获取单个字符 * @return: * @date: 2018/12/22 11:36 * @Version:1.1.0 */ private String getKeyStr(ProceedingJoinPoint pjp, String key) { Method method = ((MethodSignature) pjp.getSignature()).getMethod(); String[] parameterNames = new LocalVariableTableParameterNameDiscoverer() .getParameterNames(method); return SpelEl.getEntityKey(key, parameterNames, pjp.getArgs()); } /** * @param pjp :注入对象 * @功能描述: 获取对象 * @return: * @date: 2018/12/22 11:35 * @Version:1.1.0 */ private Object getKeyEntity(ProceedingJoinPoint pjp, String key) { Method method = ((MethodSignature) pjp.getSignature()).getMethod(); String[] parameterNames = new LocalVariableTableParameterNameDiscoverer() .getParameterNames(method); return SpelEl.getKeyEntity(key, parameterNames, pjp.getArgs()); } /** * @功能描述: 根据属性名称获取属性的对应值 * @param: fieldName-属性名称 * @param: o-类对象 * @return: Object * @date: 2018/12/18 10:41 * @Version:1.1.0 */ private static Object executionNoParameterMethod(String fieldName, Object o) { try { Method method = o.getClass().getMethod(fieldName, new Class[]{}); Object value = method.invoke(o, new Object[]{}); return value; } catch (Exception e) { LOGGER.info("executionNoParameterMethod执行异常[{}]", e.getMessage()); e.printStackTrace(); return null; } } /** * @param methodName 方法名称 * @param obj 调用此方法的对象 * @param args 调用的这个方法的参数参数列表 * @功能描述: 执行带参数的方法 * @return: Object * @date: 2018/12/22 14:15 * @Version:1.1.0 */ public static Object executionParameterMethod(String methodName, Object obj, Object[] args) { Class c[] = null; //1.参数存在 if (args != null) { int len = args.length; c = new Class[len]; for (int i = 0; i < len; ++i) { c[i] = args[i].getClass(); } } try { Method method = obj.getClass().getDeclaredMethod(methodName, c); LOGGER.error("----------反射调用:方法名称-----------------:[{}]", method.getName()); try { Object value = method.invoke(obj, args); LOGGER.error("----------反射调用:方法名称-返回结果----------------:[{}]", value.toString()); return value; } catch (Exception ex) { ex.printStackTrace(); LOGGER.error("反射调用:方法名称:[{}],Exception ex 错误码:[{}]", MethodAspect.class.getName(), ex.getMessage()); return null; } } catch (Exception ex) { ex.printStackTrace(); LOGGER.error("反射调用:obj.getClass().getDeclaredMethod(methodName, c)方法名称:[{}]", MethodAspect.class.getName()); return null; } } }
使用案列方法: 面向注解的切面编码
MethodEnum.RECHECK_BOX_NO_ONE:对象的是指定类里面的方法名称 #omPdaBoxDto:spring的service类中方法的入参属性名 @VerificationMethod(method = MethodEnum.RECHECK_BOX_NO_ONE, entryKey = "#omPdaBoxDto") public ResultData<OmPdaBoxVo> selectOmPdaBoxVo(OmPdaBoxDto omPdaBoxDto) { return ResultData.ok(); }
如有疑问加QQ:841495046 一起探讨,一起成长