Статьи

Подключение к EJB из Spring


При подготовке моего следующего упражнения я должен был сначала найти способ подключения к удаленной SLSB из Spring.

Это оказалось по-детски просто. Посмотри, как я это сделал.


Написание компонента SLSB

Сначала мне понадобился удаленный SLSB.

С помощью M2Eclipse создайте проект Maven 2. В окне выбора архетипов я набрал mojo в поле фильтра (архетипы mojo — это архетипы codehaus, о которых я писал в:
Не используйте org.apache.maven.archetypes! ) И выбрал архетип ejb3.

Я написал простой компонент SLSB:

package org.xh.studies.openejb;
import javax.ejb.Remote;
@Remote
public interface Greeter {
 String sayHello(String to);
}

package org.xh.studies.openejb;
import javax.ejb.Stateless;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@Stateless
public class GreeterImpl implements Greeter { 
 private static final Log log = LogFactory.getLog(GreeterImpl.class);
 public String sayHello(String to) {
  log.info("Saying hi to: " + to);
  return "Hello " + to + "! How are you?";
 }
}

Я построил это с:

mvn package

Развертывание в OpenEJB

Я скачал архив OpenEJB отсюда:
http://openejb.apache.org/download.html и распаковал его. Я закончил установку ?

Я скопировал встроенный jar-файл предыдущего шага в каталог приложений, затем пошел в каталог bin и запустил openejb (.bat).

Написание интеграционного теста JUnit

Сначала я написал простой интеграционный тест (использующий отказоустойчивый плагин, в моем блоге много постов об этом, ключевой из которых:
интеграционное тестирование Maven2 с отказоустойчивыми плагинами и подключаемыми модулями ), чтобы проверить, действительно ли работает SLSB:

public class GreeterIT {
 private static Context ctx;
 @BeforeClass
 public static void setUp() throws NamingException {
  Properties env = new Properties();
  env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
  env.put(Context.PROVIDER_URL, "ejbd://localhost:4201");
  ctx = new InitialContext(env);
 }
 @AfterClass
 public static void tearDown() throws NamingException {
  ctx.close();
 }
 @Test
 public void sayHelloRemoteEJBTest() throws NamingException {
  Greeter greeter = (Greeter) ctx.lookup("GreeterImplRemote");
  String result = greeter.sayHello("Łukasz");
  String expected = "Hello Łukasz! How are you?";
  Assert.assertEquals(expected, result);
 }
}

Я провел тест, и он прошел.

Соединяясь с EJB из Spring,

я обнаружил компонент Spring с именем org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean. Он использует AOP рядом со сценами для создания прокси для удаленной SLSB. Все, что вам нужно, это просто интерфейс.

Сначала мне нужно было добавить зависимости Spring в мой pom.xml. Это были:

spring-beans
spring-context
spring-aop

Затем я создал файл с именем META-INF / spring / beans.xml и написал:

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
  <property name="environment">
   <props>
    <prop key="java.naming.factory.initial">org.apache.openejb.client.RemoteInitialContextFactory</prop>
    <prop key="java.naming.provider.url">ejbd://localhost:4201</prop>
   </props>
  </property>
 </bean>
 <bean id="greeterBean"
  class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
  <property name="jndiName" value="GreeterImplRemote" />
  <property name="jndiTemplate" ref="jndiTemplate" />
  <property name="businessInterface" value="org.xh.studies.openejb.Greeter" />
 </bean>
</beans>

В приведенном выше файле я создал greeterBean, который был динамическим прокси-сервером и, благодаря AOP, вел себя как объект Greeter.

При написании теста Spring

я добавил еще одно поле в свой тест:

private static ApplicationContext springCtx;

Затем в классе @BeforeClass я добавил код инициализации ApplicationContext:

springCtx = new ClassPathXmlApplicationContext("META-INF/spring/beans.xml");

Наконец, я написал новый метод для тестирования того, что я собирался сделать первым, подключившись к удаленной SLSB из Spring:

@Test
public void sayHelloSpringProxyTest() throws NamingException {
 Greeter greeter = (Greeter) springCtx.getBean("greeterBean");
 String result = greeter.sayHello("Łukasz");
 String expected = "Hello Łukasz! How are you?";
 Assert.assertEquals(expected, result);
}

Это сработало!

Загрузка

исходного кода Полная загрузка исходного кода может быть найдена здесь:
Connecting-to-EJB-from-Spring.zip .

Резюме

Разве это не красиво? Вы получаете экземпляр удаленного SLSB в виде bean-компонента Spring. Мне определенно нравится это!

спасибо,

Лукаш