Crear anotaciones en Java
Cuando nos encontramos trabajando en muchas ocasiones vamos a necesitar alguna customización o anotación propia para nuestro servicio. En esta entrada vamos a ver como podemos solventar estos problemas al crear anotaciones en Java propias.
Las anotaciones fueron introducidas en Java 1.5 y desde entonces es una herramienta usada por todos los desarrolladores así como por los frameworks.
Crear una intefaz para crear anotaciones en Java
Antes de ver una creación vamos a ver los diferentes tipos a los que podemos aplicar nuestras anotaciones:
- Type
- Field
- Method
- Parameter
- Constructor
- Local_Variable
- Annotation_Type
- Package
- Module
- Type_Parameter
- Type_use
Para la creación de una anotación comenzamos creando una interfaz en Java, el nombre de esta interfaz será que la que será invocada añadiendo el prefijo @.
public @interface ValidateUUID { }
Una vez creamos la interfaz con el nombre que queremos tener es el momento de añadir las meta-annotations para especificar el scope y el target:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.Type) public @interface ValidateUUID { }
Nuestra anotación tendrá efecto en tiempo de ejecución y podrá ser aplicada a tipos (clases).
Dentro de una anotación se pueden añadir campos:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyAnnotation { public String name(); public String value(); }
Procesamiento de anotaciones
Una vez hemos creado la anotación podemos acceder a ellas en los diferentes niveles. Por ejemplo vamos a ver como acceder a nivel de clase y de campo:
Acceso a anotaciones a Nivel de Clases
Por ejemplo podemos acceder a nivel de clase a una anotación concreta de la siguiente manera:
@MyAnnotation(name="myName", value = "a lot") public class TheClass { }
Class aClass = TheClass.class; Annotation annotation = aClass.getAnnotation(MyAnnotation.class); if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); }
Acceso a Nivel de Campo
Como hemos comentado antes las anotaciones también pueden ser creadas a nivel de campo, para ello podemos al igual que accedemos a nivel de clase acceder a nivel de campo:
public class MyClass { @MyAnnotation(name="noel", value = "annotations") public String myField = null; }
Field field = ... // obtain method object Annotation annotation = field.getAnnotation(MyAnnotation.class); if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); }
Ejemplo de creación de anotaciones en Java
Nuestras anotaciones pueden validar nuestros campos, métodos o clases através del API de Java Reflection o con Programación Orientada a Aspectos. Por ejemplo vamos a crear una anotación a nivel de campo que se encargará de transformar a Json lo que le venga en un campo.
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface JsonConverter{ public String key() default ""; }
La anotación declara un parámetro de tipo String con un valor vacío por defecto.
Vamos a crear el código necesario para verificuar que nuestro Id es un valor String, por lo que lo primero sería hacer el siguiente control:
private void transformToJson(Object object) { if (Objects.isNull(object)) { throw new NotFoundException("Object not found"); } Field field = object.getClass().getDeclaredField(fieldName); Annotation[] annotations = field.getDeclaredAnnotations(); if (null == annotations || annotations.isEmpty() { throw new NotFoundException("Annotations not found"); } }
El primer paso ha sido verificar que existe la anotación y ahora le añadiremos lógica para verificar que el id es correcto.
private String fromStringToJson(Object object) throws Exception { Class<?> clazz = object.getClass(); Map<String, String> elements= new HashMap<>(); for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); if (field.isAnnotationPresent(JsonConverter.class)) { elements.put(getKey(field), (String) field.get(object)); } } String jsonObject= elements.entrySet() .stream() .map(entry -> "\"" + entry.getKey() + "\":\"" + entry.getValue() + "\"") .collect(Collectors.joining(",")); return "{" + jsonObject+ "}"; }
Una vez hemos creado creado la clase encargada que convertirá la anotación o anotaciones de los campos de una clase a Json es el momento de llamarla desde la clase principal.
public class JsonConverterObject { public String converter(Object object) throws JsonSerializationException { try { transformToJson(object); return fromStringToJson(object); } catch (Exception e) { log.error("Error proccesing the json field"); throw new JsonSerializationException(e.getMessage()); } } }
Conclusión
En esta entrada hemos visto como podemos crear anotaciones en Java para nuestras aplicaciones a distintos niveles. Estas anotaciones nos serán de gran utilidad para evitar repetir código y simplificar todo lo posible la aplicación.
Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com o también nos puedes contactar por nuestras redes sociales Facebook o twitter y te ayudaremos encantados!