Eliminan la obligatoriedad de distribuir nuestros objetos (ya que solo en algunos pocos casos es necesario), con la consiguiente mejora de performance, y por lo tanto eliminan la necesidad de lidiar con RemoteException en cada método. Es de destacar también que las interfaces locales utilizan llamadas por referencia, a diferencia de utilizar llamadas por valor (copias de objetos serializados) en la interfaz remota. Para ello, el servidor de aplicaciones instancia nuestros EJBs en la misma JVM que, por ejemplo, la capa de presentación web desde donde son llamados.
Pero no todo es color de rosa con los EJBs, ya que seguimos teniendo clases que son difíciles de probar (con JUnit, por ejemplo), y seguimos teniendo el añadido (en contraposición a utilizar POJOs para nuestros objetos de negocio) de complicar el desarrollo con interfaces y descriptores.
Pero veamos como utilizar Spring para simplificar el desarrollo en el caso que no poder reemplazar los EJBs por POJOs + AOP/ORM/JDBC.
Para utilizar un EJB tradicionalmente se ocultan las búsquedas JNDI detrás de un Service Locator que nos devuelve un objeto EJB Home, el cual a su vez utilizamos para obtener el EJB real (local o remoto) mediante una llamada al método create.
Esto no nos libra de tener que implementar también un Business Delegate para despegar al cliente de la utilización directa de la API de EJB, y por lo tanto de las RemoteException lanzadas por su método de networking.
El método de Spring para simplificar lo anteriormente expuesto es la utilización de proxys dentro del ApplicationContext, que nos libran de escribir un nuevo Service Locator y/o Business Delegate para nuestro objeto de negocio.
Utilizando el mismo ejemplo que la documentación de Spring, lo primero que haremos será seguir las buenas prácticas y construir una Business Methods Interface para nuestro componente. Este patrón nos asegura una correcta sincronización entre el nuestro objeto de negocio y la interfaz (local o remota), ya que ambos implementan la misma Business Method Interface. Otra razón para utilizar este patrón, es que nos será mas fácil intercambiar una implementación EJB por otra POJO, si mas adelante lo consideramos necesario:
public interface MyComponent {Luego expondremos una propiedad en el objeto cliente (un web controller en el ejemplo de Spring):
...
}
private MyComponent myComponent;y finalmente configuraremos las dependencias en el xml de configuración de Spring:
public void setMyComponent(MyComponent myComponent) {
this.myComponent = myComponent;
}
<bean id="myComponent"Lo que sucede luego, es que Spring (gracias a AOP) crea un proxy para el EJB, el cual implementa dinámicamente nuestra Business Methods Interface (MyComponent) y hace las búsquedas JNDI necesarias para encontrar el EJB Local Home (el cual pone en cache).
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName"><value>myComponent</value></property>
<property name="businessInterface"><value>com.mycom.MyComponent</value></property>
</bean>
<bean id="myController" class="com.mycom.myController">
<property name="myComponent"><ref bean="myComponent"/></property>
</bean>
Ante cada llamada del cliente a myComponent, Spring hará la llamada correspondiente a create para obtener el EJB y al correspondiente método en el objeto de negocio.
Si por cualquier razón queremos cambiar la implementación del objeto de negocio de un EJB a un POJO, simplemente cambiamos la definición del bean en Spring sin necesidad de tocar una sola linea de código en el cliente:
<bean id="myComponent"Esta facilidad para cambiar de EJBs a POJOs, sugiere que es posible, en una aplicación existente que utiliza extensivamente EJBs, ir reemplazando primero la infraestructura de configuración de dependencias, luego la de acceso a los objetos de negocio y finalmente la implementación misma de estos objetos. Asi resulta mucho menos traumático para el equipo de desarrollo, y menos estresante para la dirección.
class="com.example.MyBusinessObject">
</bean>
Actualización: El artículo Pro Spring: Spring and EJB (en inglés) presenta el mismo tema en forma mucho mas extensa.