EJB 3.1 @LocalBean vs sin anotación

Entiendo la diferencia entre la vista local, la vista remota y la vista sin interfaz. Simplemente no entiendo cuál es la diferencia entre “sin vista” (sin anotación) y vista sin interfaz. Y también ¿por qué debería anotar mi interfaz con @Local ? ¿Qué ocurre si no anoto la interfaz en absoluto? ¿Hay alguna diferencia?

Las reglas son (desde la memoria):

  1. Bean tiene una anotación @LocalBean -> bean tiene una vista sin interfaz
  2. Bean tiene una anotación @Local -> bean tiene una vista local
  3. Bean tiene una anotación @Remote -> bean tiene una vista remota
  4. Bean no tiene anotaciones de vista, pero implementa directamente una interfaz que tiene una anotación @Local -> bean tiene una vista local
  5. Bean no tiene anotaciones de vista, pero implementa directamente una interfaz que tiene una anotación @Remote -> bean tiene una vista remota
  6. Bean no tiene anotaciones de vista, pero implementa directamente una interfaz que no tiene anotaciones de vista -> bean tiene una vista local
  7. Bean no tiene anotaciones de vista, y no implementa interfaces -> bean tiene una vista sin interfaz

Entonces, usar @LocalBean y no usar ninguna anotación son ambas formas de obtener una vista sin interfaz. Si solo desea una vista sin interfaz, lo más simple es no hacer anotaciones. Siempre que no esté implementando ninguna interfaz.

Parte de la razón por la cual @LocalBean existe para agregar una vista sin interfaz a un bean que también tiene una vista de interfaz. Me imagino que el escenario más importante en las mentes de los autores de las especificaciones es uno en el que tienes un frijol como:

 @Stateless public class UserPreferences { public String getPreference(String preferenceName); public Map getPreferences(); } 

Donde desearía exponer ambos métodos localmente, pero solo las getPreferences() grano más grueso getPreferences() forma remota. Puedes hacer eso declarando una interfaz remota con solo ese método, y luego @LocalBean en la clase de bean. Sin él, tendrías que escribir una interfaz local sin sentido solo para exponer ambos métodos localmente.

O, para verlo de otra manera, el @LocalBean existe porque existe una vista sin interfaz, y la opción sin anotación existe como un atajo práctico.

  • EJB remotos: se puede acceder desde clientes remotos (clientes que se ejecutan en una JVM diferente, como clientes Swing o JavaFX que se ejecutan en la máquina del usuario)
  • EJB locales: solo se puede acceder desde otros “componentes” que se ejecutan en la misma JVM, por ejemplo, Web Front-ends, otros EJB
  • Vista sin interfaz: igual que Local, pero sin especificar la interfaz comercial
  • Sin anotaciones: un POJO simple pero no un EJB

Las vistas locales / sin interfaz son más eficientes que los EJB remotos, ya que las referencias a objetos se pueden pasar.

Creo que la confusión que sentimos es resultado de la historia / retrocompatibilidad (por así decirlo). No puedo distinguir ninguna diferencia (excepto que la especificación requiere implementaciones para crear una interfaz si usamos la vista local)

La vista sin interfaz tiene el mismo comportamiento que la vista local de EJB 3.0, por ejemplo, admite funciones como la semántica de llamadas de paso por referencia y la propagación de transacciones y seguridad. Sin embargo, una vista sin interfaz no requiere una interfaz separada, es decir, todos los métodos públicos de la clase de bean se exponen automáticamente a la persona que llama. De forma predeterminada, cualquier bean de sesión que tenga una cláusula de implementaciones vacía y no defina ninguna otra vista de cliente local o remota, expone una vista de cliente sin interfaz.

Oracle Blog antes del lanzamiento de EJB 3.1

Si está interesado en más detalles técnicos, permítame decir que lo que está sucediendo realmente … No tiene acceso directo al objeto EJB, significa que no tiene la referencia (dirección) del objeto EJB real. Cuando busca o inyecta su EJB, el contenedor proporciona un objeto como el cliente para ese EJB (podemos llamar proxy o Wrapper) e invoca sus métodos comerciales en ese objeto proxy. (Es por eso que no debe usar una nueva palabra clave para crear el objeto de la clase EJB)

Ahora, para cada tipo de anotación, el contenedor genera diferentes tipos de proxies con diferentes métodos y funcionalidades.

@LocalBean (o sin anotación) Su objeto proxy tiene:

  • setOptionalLocalIntfProxy()
  • getSerializableObjectFactory()

@Local objeto proxy utiliza la llamada local y el tipo de com.sun.proxy Por lo tanto, tiene:

  • getSerializableObjectFactory()
  • isProxyClass()
  • getProxyClass()
  • getInvocationHandler()
  • newProxyInstance()

@Remote You Wrapper object usa la llamada remota y tiene:

  • readResolve()
  • writeReplace()
  • getStub()
  • getBusinessInterfaceName()