ReflectionExt { public static <T, A extends Annotation> List<Method> findAnnotatedMethods(T instance, Class<A> methodAnnotation) { Class<?> instanceType = bypassBytecodeGeneratedWrappers(instance); List<Method> result = new ArrayList<>(); for (Method m : instanceType.getMethods()) { for (Annotation a : m.getAnnotations()) { if (a.annotationType() == methodAnnotation) { result.add(m); } } } return result; } private  ReflectionExt(); static boolean isPrimitiveOrWrapper(Class<?> type); static boolean isStandardDataType(Class<?> type); static boolean isContainerType(Field field); static boolean isNumeric(Class<?> type); static boolean isObjectMethod(Method method); static List<Class<?>> findAllInterfaces(Class<?> type); static List<Method> findAnnotatedMethods(T instance, Class<A> methodAnnotation); static Optional<StackTraceElement> findCallerStackTrace(); static Optional<Method> findInterfaceMethod(Method method); static Field getField(Class<?> type, String name); static T getFieldValue(Field field, Object object); static List<Field> getAllFields(Class<?> type); static Object invokeDefault(Object proxy, Class<?> apiInterface, Method method, Object[] args);  }
@Test public void testFindAnnotatedMethods() { List<Method> annotatedMethods = ReflectionExt.findAnnotatedMethods(new MyServiceImpl(), PostConstruct.class); assertThat(annotatedMethods).hasSize(1); assertThat(annotatedMethods.get(0).getName()).isEqualTo("classAnnotated"); }