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 57 58
| @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CollectArguments { }
@Aspect public class ArgumentsCollector {
private static final ThreadLocal<Map<String, Object>> ARGUMENTS = ThreadLocal.withInitial(ImmutableMap::of);
static Map<String, Object> getArgs() { return ARGUMENTS.get(); }
private Object[] args(Object[] args, int exceptLength) { if (exceptLength == args.length) { return args; }
return Arrays.copyOf(args, exceptLength); }
@Pointcut("@annotation(CollectArguments)") void collectArgumentsAnnotationPointCut() { }
@Before("collectArgumentsAnnotationPointCut()") public void doAccessCheck(JoinPoint joinPoint) { final String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames(); final Object[] args = args(joinPoint.getArgs(), parameterNames.length);
ARGUMENTS.set(Collections.unmodifiableMap((IntStream.range(0, parameterNames.length - 1) .mapToObj(idx -> Tuple2.of(parameterNames[idx], args[idx])) .collect(HashMap::new, (m, t) -> m.put(t.getT1(), t.getT2()), HashMap::putAll)))); }
@After("collectArgumentsAnnotationPointCut()") public void remove() { ARGUMENTS.remove(); }
@Data private static class Tuple2<T1, T2> {
private T1 t1; private T2 t2;
Tuple2(T1 t1, T2 t2) { this.t1 = t1; this.t2 = t2; }
public static <T1, T2> Tuple2<T1, T2> of(T1 t1, T2 t2) { return new Tuple2<>(t1, t2); } } }
|