# Jakarta Annotations en Quarkus: Gestión del Ciclo de Vida y Anotaciones Personalizadas

## **Introducción**

Jakarta Annotations proporciona anotaciones estándar para gestionar el ciclo de vida de componentes y crear anotaciones personalizadas. En Quarkus, estas anotaciones están completamente soportadas y funcionan de forma integrada con CDI.

## **¿Qué son las Anotaciones?**

Las anotaciones en Java son metadatos que se pueden agregar a clases, métodos, campos y otros elementos del código. Jakarta EE define varias anotaciones estándar para gestionar el ciclo de vida y comportamiento de los componentes.

## **Anotaciones Estándar de Jakarta**

### **@PostConstruct**

Se ejecuta después de que el bean ha sido construido e inyectado:

```go
@ApplicationScoped
public class HeroService {
    
    @PostConstruct
    public void init() {
        // Se ejecuta después de la construcción
        // Útil para inicialización
        logger.info("HeroService initialized");
    }
}
```

### **@PreDestroy**

Se ejecuta antes de que el bean sea destruido:

```go
@ApplicationScoped
public class HeroService {
    
    @PreDestroy
    public void cleanup() {
        // Se ejecuta antes de la destrucción
        // Útil para liberar recursos
        logger.info("HeroService cleaning up");
    }
}
```

### **@Resource**

Inyecta recursos del contenedor:

```go
@ApplicationScoped
public class HeroService {
    
    @Resource
    private Logger logger;
    
    @Resource(name = "jdbc/heroesDB")
    private DataSource dataSource;
}
```

### **@Generated**

Marca código generado automáticamente:

```go
@Generated(value = "code-generator", date = "2024-01-01")
public class GeneratedHero {
    // Código generado
}
```

## **Anotaciones Personalizadas**

### **Crear una Anotación Personalizada**

```go
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface HeroPower {
    int minLevel() default 1;
    String description() default "";
}
```

### **Usar la Anotación**

```go
@HeroPower(minLevel = 80, description = "Héroe poderoso")
@Loggable(level = "INFO")
public void activateHero(String name) {
    // Método marcado con anotaciones personalizadas
}
```

### **Anotación para Logging**

```go
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {
    String level() default "DEBUG";
    boolean includeArgs() default true;
    boolean includeResult() default false;
}
```

### **Anotación para Validación**

```go
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PowerLevelValidator.class)
public @interface PowerLevel {
    String message() default "Nivel de poder inválido";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    
    int min() default 1;
    int max() default 100;
}
```

## **Procesamiento de Anotaciones**

### **Leer Anotaciones en Runtime**

```go
public void processAnnotations(Object obj) {
    Class<?> clazz = obj.getClass();
    
    // Leer anotaciones de clase
    if (clazz.isAnnotationPresent(HeroPower.class)) {
        HeroPower annotation = clazz.getAnnotation(HeroPower.class);
        int minLevel = annotation.minLevel();
        String description = annotation.description();
    }
    
    // Leer anotaciones de métodos
    for (Method method : clazz.getDeclaredMethods()) {
        if (method.isAnnotationPresent(HeroPower.class)) {
            HeroPower annotation = method.getAnnotation(HeroPower.class);
            // Procesar método
        }
    }
}
```

## **Ejemplo Completo: Servicio con Anotaciones**

```go
@ApplicationScoped
public class HeroService {
    
    private List<Hero> heroes = new ArrayList<>();
    
    @PostConstruct
    public void init() {
        // Inicializar datos después de la construcción
        heroes.add(new Hero("Superman", "Super fuerza", 95));
        heroes.add(new Hero("Batman", "Inteligencia", 85));
        logger.info("HeroService initialized with " + heroes.size() + " heroes");
    }
    
    @PreDestroy
    public void cleanup() {
        // Limpiar recursos antes de destruir
        heroes.clear();
        logger.info("HeroService cleaned up");
    }
    
    @HeroPower(minLevel = 80)
    @Loggable(level = "INFO")
    public Hero getPowerfulHero(String name) {
        return heroes.stream()
            .filter(h -> h.getName().equals(name))
            .filter(h -> h.getPowerLevel() >= 80)
            .findFirst()
            .orElse(null);
    }
}
```

## **Ciclo de Vida de Beans con Anotaciones**

El ciclo de vida de un bean en Quarkus con CDI:

1. **Construcción**: El bean se instancia
    
2. **Inyección**: Las dependencias se inyectan
    
3. **@PostConstruct**: Se ejecuta el método marcado
    
4. **Uso**: El bean está listo para usar
    
5. **@PreDestroy**: Se ejecuta antes de destruir (al cerrar la aplicación)
    

## **Anotaciones y CDI**

Las anotaciones funcionan perfectamente con CDI:

```go
@ApplicationScoped
@HeroPower(minLevel = 70)
public class PowerAnalysisService {
    
    @Inject
    HeroService heroService;
    
    @PostConstruct
    public void initialize() {
        // Inicialización después de la construcción e inyección
    }
}
```

## **Ejemplo Completo**

Nuestro demo muestra:

* @PostConstruct y @PreDestroy para ciclo de vida
    
* @Resource para inyección de recursos
    
* @Generated para código generado
    
* Anotaciones personalizadas (@HeroPower, @Loggable, @PowerLevel)
    
* Procesamiento de anotaciones en runtime
    

## **Ventajas en Quarkus**

1. **Integración CDI**: Funciona perfectamente con CDI
    
2. **Ciclo de Vida**: Gestión automática del ciclo de vida
    
3. **Flexibilidad**: Fácil crear anotaciones personalizadas
    
4. **Metadatos**: Las anotaciones proporcionan metadatos útiles
    

## **Casos de Uso**

### **Inicialización de Servicios**

```go
@PostConstruct
public void init() {
    // Cargar configuración
    // Inicializar conexiones
    // Preparar datos en memoria
}
```

### **Limpieza de Recursos**

```go
@PreDestroy
public void cleanup() {
    // Cerrar conexiones
    // Liberar recursos
    // Guardar estado
}
```

### **Anotaciones de Dominio**

```go
@HeroPower(minLevel = 90)
public class LegendaryHeroService {
    // Servicio para héroes legendarios
}
```

## **Conclusión**

Las anotaciones en Quarkus proporcionan una forma poderosa de gestionar el ciclo de vida y agregar metadatos al código. Las anotaciones estándar como @PostConstruct y @PreDestroy son esenciales, mientras que las anotaciones personalizadas permiten crear APIs específicas del dominio.

## **Recursos**

* [Demo completo](file:///Users/josediaz/Projects/JoeDayz/jakartaee-2026/quarkus-demos/annotations/)
    
* [Jakarta Annotations Specification](https://jakarta.ee/specifications/annotations/)
    
* [Quarkus CDI Guide](https://quarkus.io/guides/cdi-reference)
