This post presents a simple (yet powerful) way to combine reflection and annotations to obtain all the methods present in a class' hierarchy marked with a given annotation.
It could be very useful in a variety of scenarios, e.g. auditing: by just annotating the getters in the audited entity, we'll be able to keep track of the values/changes with a few lines of code:
package bar.foo.utils;
public class ReflectionUtils {
/**
* Enforce non-instatiability
*/
private ReflectionUtils {}
/**
* Get all methods annotated with the specified annotation
* searching on the leaf class and all superclasses.
*/
public static Method[] getAllAnnotatedMethods(
Class targetClass, Class annotationClass) {
List list = new ArrayList();
// traverse inheritance hierarchy
do {
Method[] methods = targetClass.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(annotationClass))
methods.add(method);
}
targetClass = targetClass.getSuperclass();
} while (targetClass != null);
return (Method[]) list.toArray(new Method[list.size()]);
}
}
It could be very useful in a variety of scenarios, e.g. auditing: by just annotating the getters in the audited entity, we'll be able to keep track of the values/changes with a few lines of code:
public class Entity extends BaseEntity {
private Integer id;
private MyProperty myProperty;
// we don't want to audit id!
public Integer getId() {return id;}
// but we do want to audit myProperty
@Auditable
public MyProperty getMyProperty {return myProperty;}
}
...
public class AuditManager {
public void auditEntity(BaseEntity myEntity) {
Class entityClass = myEntity.getClass();
Class annotationClass = Auditable.getClass();
Method[] auditGetters = ReflectionUtils.getAllAnnotatedMethods(
entityClass, annotationClass);
for (Method method : auditGetters) {
// audit logic here
}
}