what tutorial produces injection example dependency java-ee java-ee-6 cdi jboss-weld

java-ee - produces - tutorial cdi java



Cómo inyectar una clase no serializable(como java.util.ResourceBundle) con Weld (2)

Quiero crear un Productor que permita inyectar un java.util.ResourceBundle en cualquier clase para obtener Cadenas localizadas fácilmente. Mi ResourceBundle-Producer se ve así:

public class ResourceBundleProducer { @Inject public Locale locale; @Inject public FacesContext facesContext; @Produces public ResourceBundle getResourceBundle() { return ResourceBundle.getBundle("/messages", locale ) } }

Las obras Injection of Locale y FacesContext (tomaron los productores correspondientes de Seam 3 Alpha Source). Desafortunadamente, ResourceBundle no es Serializable y, por lo tanto, no se puede producir de esta manera. Obtengo el siguiente error de Weld al intentar acceder a una página JSF que llama a un bean que usa mi ResourceBundle:

Caused by: org.jboss.weld.IllegalProductException: WELD-000054 Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans//n//nProducer/: org.jboss.weld.bean-/D:/Program Files (x86)/GlassFish-Tools-Bundle-For-Eclipse-1.2/glassfishv3/glassfish/domains/teachernews/applications/teachernews/-ProducerMethod-services.producers.ResourceBundleProducer.getResourceBundle()//nInjection Point/: field web.PersonHome.bundle

¿Hay alguna forma de que mi ResourceBundleResolver funcione? ¿O hay otros mecanismos para obtener una funcionalidad similar? ¡Gracias por adelantado!

EDITAR:

De acuerdo, gastaré algunos de mis puntos apenas ganados;) ¡También aceptaré una buena solución para este problema!

Tengo otro ejemplo donde la creación de un Productor no funciona: un FlashProducer. Un FacesContext-Flash tampoco se puede producir porque Flash no es serializable.


Bueno, en primer lugar ResourceBundle no es serializable . Mira aquí . Y el mensaje es claro

no puede producir instancias no serializables para inyección en campos no transitorios de pasivación de granos

pasivando frijoles ??? Creo que web.PersonHome es un bean de sesión Stateful o un bean @ConversationScoped. ¿Estoy en lo cierto? Si es así, debe marcar la propiedad del paquete como transitoria

private transient @Inject ResourceBundle bundle;


Según el hilo de comentarios en la respuesta aceptada de Arthur. Seguí este blog tan bien como este para llevar a cabo un experimento de pasivación / activación. El experimento demostró que el Sr.D comenta que la propiedad transitoria será NULL tras la activación. Por lo tanto, para tratar con las propiedades de miembros no serializables de un bean con capacidad de pasivación (es decir, sessionscoped, conversationscoped y beans de sesión con estado), sugiero la siguiente solución:

private ResourceBundle bundle; @PostConstruct @PostActivate public void getResourceBundle() { bundle = ResourceBundle.getBundle("/messages", locale ); }

Esta solución asegura que los miembros de propiedades no serializables se reinician cada vez que ingresan al estado LISTO.

Un último problema para abordar

Un último problema para abordar es la inyección de un registrador SLF4j que no era serializable antes de slf4j 1.5.3, y cito :

A partir de SLF4J versión 1.5.3, las instancias del registrador sobreviven a la serialización. Por lo tanto, la serialización de la clase de host ya no requiere ninguna acción especial, incluso cuando los registradores se declaran como variables de instancia.

Por lo tanto, siempre que su dependencia slf4j sea 1.5.3 o posterior, puede inyectar de forma segura un registrador SLF4j de la siguiente manera:

@Produces @LogbackLogger public Logger produceLogger(InjectionPoint injectionPoint){ return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName()); }

Suponiendo que haya declarado el calificador:

@Qualifier @Retention(RUNTIME) @Target({METHOD, FIELD, PARAMETER, TYPE}) public @interface LogbackLogger { }

Luego, en un frijol apta para pasivación, inyecta de la siguiente manera:

@Inject @LogbackLogger private Logger logger;