2010-07-07 24 views
11

quiero escribir esta pieza de código:¿Inyectando un EJB estático, tonterías?

@Stateless 
public class MyEjb 
{ 
    @EJB 
    private static MyOtherEjbWhichIWantStatic myOtherEjb; 
} 

Tiene sentido para mí, que yo quiero para inyectar un EJB en mi clase, como un elemento estático, por diversas razones.

Java no está muy contenta con que, lamentablemente,

com.sun.enterprise.container.common.spi.util.InjectionException: Illegal use of static field private static MyOtherEjbWhichIWantStatic myOtherEjb on class that only supports instance-based injection 

Yo no lo entiendo, ¿por qué no puedo inyectar un EJB estática en otro EJB?

Respuesta

26

Como otros señalaron, esto no está permitido por la especificación, y la versión corta es que la @EJB anotación sólo se admite para los miembros estáticos en clases con una función main() (véase la especificación EJB 3.0 y el contenedor de cliente aplicación).

¿Por qué es así? En primer lugar, campos estáticos de lectura/escritura están totalmente prohibidos en los EJB (esto es parte de la restricción EJB).De Why can't I use nonfinal static fields in my enterprise bean?

campos estáticos de clase no final no están permitidos en los EJB porque tales campos hacen un bean empresarial difícil o imposible para distribuir. Los campos de clase estáticos se comparten entre todas las instancias de una clase en particular, pero solo dentro de una única máquina virtual Java (JVM). La actualización de un campo de clase estático implica la intención de compartir el valor del campo entre todas las instancias de la clase. Pero si una clase se ejecuta simultáneamente en varias JVM, solo aquellas instancias que se ejecutan en la misma JVM que la instancia de actualización tendrán acceso al nuevo valor. En otras palabras, un campo de clase estática no final se comportará de manera diferente si se ejecuta en una sola JVM, de lo que se ejecutará en varias JVM. El contenedor EJB se reserva la opción de distribuir enterprise beans en varias JVM (que se ejecutan en el mismo servidor o en cualquier clúster de servidores). Los campos de clases estáticas no finales no se permiten porque las instancias de bean enterprise se comportarán de manera diferente dependiendo de si están distribuidas o no.

Es práctica aceptable utilizar campos de clases estáticas si esos campos están marcados como final. Como los campos finales no pueden actualizarse, el contenedor puede distribuir las instancias del enterprise bean sin preocuparse de que los valores de esos campos se desincronicen.

Pero al utilizar campos estáticos de solo lectura está permitido, esto no sería apropiado para los EJB. Los EJB sin estado se pueden agrupar, un contenedor puede decidir destruirlos (esto es específico de la implementación) y desea que el contenedor elija qué instancia va a utilizar, especialmente en entornos distribuidos. En otras palabras, nunca asuma que está vinculado a una instancia particular.

Así que al final, sí, esto es una tontería.

+0

¡Claro, gracias! –

0

Según la especificación de Java EE 5, la inyección de EJB estáticos solo se permite en las clases principales de los clientes de la aplicación.

Para todas las clases, excepto para las clases principales del cliente de aplicación, los campos o métodos no deben ser estáticos. Debido a que los clientes de aplicaciones utilizan el mismo ciclo de vida que las aplicaciones J2SE, el contenedor del cliente de la aplicación no crea ninguna instancia de la clase principal del cliente de la aplicación. En cambio, se invoca el método principal estático. Para admitir la inyección para la clase principal del cliente de la aplicación, los campos o métodos anotados para la inyección deben ser estáticos.

1

Yo no lo entiendo, ¿por qué no puedo inyectar un EJB estática en otro EJB?

Debido the spec no lo permite:

5.2.3Annotations e Inyección

Como se describe en las secciones siguientes , un campo o método de ciertas clases de componentes contenedores gestionados puede anotarse para solicitar que se introduzca una entrada desde el entorno del componente de aplicación int o la clase . [...] Para todas las clases excepto para las clases principales del cliente de aplicación , los campos o métodos no deben ser estáticos.

Tenga en cuenta que la excepción (clases principales del cliente de aplicaciones) solo existe porque esas clases nunca se crean instancias. Básicamente, los campos estáticos son generalmente problemáticos, y doblemente en un servidor de aplicaciones, porque pueden eludir la separación de los hilos y las transacciones de manejo de solicitudes, que son el punto principal de usar un servidor de aplicaciones en primer lugar.