injection example español dependency bean configuration dependency-injection annotations java-ee-6 cdi

configuration - example - cdi java español



Inyección de dependencia con el archivo ".properties" (4)

Estoy usando Java EE 6 y necesito cargar la configuración desde un archivo ".properties". ¿Existe una forma recomendada (mejor práctica) de cargar los valores del archivo de configuración mediante la inyección de dependencia? Encontré anotaciones para esto en Spring, pero no he encontrado una anotación "estándar" para Java EE.

Este chico ha desarrollado una solución desde cero:

http://weblogs.java.net/blog/jjviana/archive/2010/05/18/applicaction-configuration-java-ee-6-using-cdi-simple-example

"No pude encontrar un ejemplo simple de cómo configurar tu aplicación con CDI leyendo los atributos de configuración de un archivo ..."

Pero me pregunto si hay una forma más estándar en lugar de crear una fábrica de configuración ...


A pesar de que no cubre exactamente su pregunta, esta parte de la documentación de Weld podría ser de su interés.

Habiendo mencionado esto, no, no hay una forma estándar de inyectar recursos / archivos de recursos arbitrarios. Supongo que simplemente está más allá del alcance de una especificación estandarizar un requisito tan altamente dependiente de la costumbre (Spring no es una especificación, simplemente pueden implementar lo que quieran). Sin embargo, lo que CDI proporciona es un mecanismo fuerte (también conocido como tipo seguro) para inyectar beans que contienen configuración en un lado, y un mecanismo productor flexible para leer y crear dichos beans en el otro lado. Definitivamente esta es la forma recomendada por la que preguntabas.

El enfoque al que se está vinculando es ciertamente bastante bueno, aunque podría ser demasiado para sus necesidades, dependiendo del tipo de propiedades que planea inyectar.

Una manera muy CDI-ish de continuar sería desarrollar una extensión CDI (que encapsularía muy bien todas las clases requeridas) y desplegarla independientemente con sus proyectos. Por supuesto, también puede contribuir al catálogo de extensiones de CDI o incluso a Apache Deltaspike .


Ver @ConfigProperty de Apache DeltaSpike


Anotación de configuración

package com.ubiteck.cdi; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import javax.enterprise.util.Nonbinding; import javax.inject.Qualifier; @Qualifier @Retention(RetentionPolicy.RUNTIME) public @interface InjectedConfiguration { /** * Bundle key * @return a valid bundle key or "" */ @Nonbinding String key() default ""; /** * Is it a mandatory property * @return true if mandator */ @Nonbinding boolean mandatory() default false; /** * Default value if not provided * @return default value or "" */ @Nonbinding String defaultValue() default ""; }

La fábrica de configuración podría verse así:

import java.text.MessageFormat; import java.util.MissingResourceException; import java.util.ResourceBundle; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; public class ConfigurationInjectionManager { static final String INVALID_KEY="Invalid key ''{0}''"; static final String MANDATORY_PARAM_MISSING = "No definition found for a mandatory configuration parameter : ''{0}''"; private final String BUNDLE_FILE_NAME = "configuration"; private final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_FILE_NAME); @Produces @InjectedConfiguration public String injectConfiguration(InjectionPoint ip) throws IllegalStateException { InjectedConfiguration param = ip.getAnnotated().getAnnotation(InjectedConfiguration.class); if (param.key() == null || param.key().length() == 0) { return param.defaultValue(); } String value; try { value = bundle.getString(param.key()); if (value == null || value.trim().length() == 0) { if (param.mandatory()) throw new IllegalStateException(MessageFormat.format(MANDATORY_PARAM_MISSING, new Object[]{param.key()})); else return param.defaultValue(); } return value; } catch (MissingResourceException e) { if (param.mandatory()) throw new IllegalStateException(MessageFormat.format(MANDATORY_PARAM_MISSING, new Object[]{param.key()})); return MessageFormat.format(INVALID_KEY, new Object[]{param.key()}); } }

Tutorial con explicación y prueba de Arquillian


La única forma "estándar" de hacer esto sería usar un calificador con un miembro de anotación no vinculante y asegurarse de que todas sus inyecciones tengan un ámbito dependiente. Luego, en su productor, puede obtener InjectionPoint y obtener la clave del calificador en el punto de inyección. Querrías algo como esto:

@Qualifier public @interface Property { @Nonbinding String value default ""; } ... @Inject @Property("myKey") String myKey; ... @Produces @Property public String getPropertyByKey(InjectionPoint ip) { Set<Annotation> qualifiers = ip.getQualifiers // Loop through qualifers looking for Property.class save that off return ResourceBundle.getBundle(...).getString(property.key); }

Obviamente, hay algunas mejoras que puede hacer con ese código, pero deberían ser suficientes para comenzar a seguir el camino correcto.