Volver a la página principal
martes 1 abril 2025
1

Cómo Crear Anotaciones Personalizadas en Spring Boot

Cuando trabajamos con Spring Boot, uno de los mayores beneficios es la flexibilidad y el poder de sus anotaciones. Estas anotaciones permiten simplificar el desarrollo de aplicaciones al gestionar la inyección de dependencias, la configuración automática y muchos otros aspectos del ciclo de vida de la aplicación. Pero, ¿qué sucede cuando las anotaciones predeterminadas no se ajustan exactamente a nuestras necesidades? Aquí es donde entran en juego las anotaciones personalizadas. 💡

¿Qué es una anotación personalizada en Spring Boot?

En Java, una anotación es una forma de agregar metadatos a nuestro código fuente. Spring Boot aprovecha las anotaciones para automatizar muchas tareas comunes. Una anotación personalizada es simplemente una anotación creada por nosotros mismos para cumplir una función específica en nuestra aplicación.

Estas anotaciones se pueden utilizar para:

  • Validaciones personalizadas.
  • Controlar el flujo de una aplicación.
  • Aplicar aspectos (AOP) como logging o manejo de excepciones.
  • Modularizar comportamientos repetitivos.

👉 Un ejemplo común sería una anotación que verifique permisos antes de ejecutar un método.

🛠 Paso 1: Crear una Anotación Personalizada Básica

Primero, veamos un ejemplo simple de una anotación personalizada que no hace nada especial, solo es un marcador.

1. Definiendo la Anotación

Creamos un archivo Java en nuestro proyecto llamado @MiAnotacion.java:

package com.ejemplo.anotaciones;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MiAnotacion {
    String valor() default "Hola desde la anotación personalizada";
}

Explicación del Código:

  • @Retention(RetentionPolicy.RUNTIME): Indica que la anotación estará disponible en tiempo de ejecución (ideal para aspectos o validaciones).
  • @Target(ElementType.METHOD): Restringe el uso de la anotación solo a métodos.
  • String valor(): Declaramos un atributo opcional con valor predeterminado.

🟢 Paso 2: Usar la Anotación en un Método

Ahora que tenemos nuestra anotación, probémosla en un controlador de Spring Boot:

package com.ejemplo.controlador;

import com.ejemplo.anotaciones.MiAnotacion;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MiControlador {

    @MiAnotacion(valor = "Este es un mensaje personalizado")
    @GetMapping("/saludo")
    public String saludo() {
        return "¡Hola Mundo!";
    }
}

🚀 Probando la Aplicación:

1. Inicia tu aplicación Spring Boot.

2. Ve a http://localhost:8080/saludo y verás "¡Hola Mundo!" como respuesta.

Aunque la anotación no hace nada aún, ¡ya estamos listos para agregar lógica! 😉

🟢 Paso 3: Aplicar Lógica a la Anotación con AOP (Aspect-Oriented Programming)

Vamos a darle vida a nuestra anotación usando AOP de Spring, lo que nos permitirá interceptar métodos anotados y realizar acciones antes, después o alrededor de su ejecución.

🟢 3.1 Configuración de Dependencias

Primero, asegúrate de tener la dependencia de AOP en tu pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

🟢 3.2 Creando el Aspecto (Aspect)

Creamos una clase llamada MiAspecto.java para manejar la anotación:

package com.ejemplo.aspecto;

import com.ejemplo.anotaciones.MiAnotacion;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MiAspecto {

    @Before("@annotation(miAnotacion)")
    public void antesDelMetodo(JoinPoint joinPoint, MiAnotacion miAnotacion) {
        System.out.println("Ejecutando antes del método: " + joinPoint.getSignature());
        System.out.println("Valor de la anotación: " + miAnotacion.valor());
    }
}

Explicación del Código:

  • @Aspect: Marca la clase como un aspecto que interceptará métodos.
  • @Before: Indica que el método antesDelMetodo se ejecutará antes de cualquier método anotado con @MiAnotacion.
  • JoinPoint: Proporciona información sobre el método interceptado.

🚀 Paso 4: Probando el Comportamiento de la Anotación

Reinicia tu aplicación y accede nuevamente a http://localhost:8080/saludo.

En la consola deberías ver algo como:

Ejecutando antes del método: String com.ejemplo.controlador.MiControlador.saludo()
Valor de la anotación: Este es un mensaje personalizado

¡Funciona! Ahora tenemos una anotación personalizada que ejecuta lógica antes del método anotado. 🎉

🟢 Paso 5: Caso de Uso Real - Validación Personalizada

Imaginemos que queremos validar si un usuario tiene permisos antes de ejecutar un método.

5.1 Creando la Anotación Personalizada de Permisos

package com.ejemplo.seguridad;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequierePermiso {
    String valor();
}

5.2 Implementando el Aspecto de Seguridad

package com.ejemplo.aspecto;

import com.ejemplo.seguridad.RequierePermiso;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class SeguridadAspecto {

    @Before("@annotation(requierePermiso)")
    public void validarPermiso(JoinPoint joinPoint, RequierePermiso requierePermiso) {
        String permisoRequerido = requierePermiso.valor();
        // Simulación de validación
        if (!"ADMIN".equals(permisoRequerido)) {
            throw new SecurityException("Acceso denegado");
        }
        System.out.println("Permiso validado correctamente");
    }
}

5.3 Usando la Anotación de Seguridad

package com.ejemplo.controlador;

import com.ejemplo.seguridad.RequierePermiso;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SeguridadControlador {

    @RequierePermiso(valor = "ADMIN")
    @GetMapping("/admin")
    public String accesoAdmin() {
        return "Acceso permitido";
    }
}

Ahora, si accedes a http://localhost:8080/admin, obtendrás:

  • Acceso permitido si el permiso es "ADMIN".
  • Excepción de seguridad en caso contrario.

Conclusión

Las anotaciones personalizadas en Spring Boot son una poderosa herramienta que facilita la implementación de comportamientos repetitivos y permite separar la lógica de negocio de la lógica transversal. Con AOP podemos aplicar reglas de validación, manejo de errores y cualquier otra lógica que necesitemos.

¡Espero que este artículo te haya sido útil y que te animes a usar anotaciones personalizadas en tus proyectos Spring Boot! 🚀

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer