Рубрики
Без рубрики

Руководство по интеграции пружины и EJB

Узнайте, как интегрировать корпоративные компоненты Java в приложение Spring.

Автор оригинала: baeldung.

1. Обзор

В этой статье мы покажем, как интегрировать Spring и удаленные корпоративные Java-компоненты (EJB) .

Для этого мы создадим несколько EJB и необходимые удаленные интерфейсы, а затем запустим их в контейнере JEE. После этого мы запустим наше приложение Spring и, используя удаленные интерфейсы, создадим экземпляры наших компонентов, чтобы они могли выполнять удаленные вызовы.

Если есть какие-либо сомнения относительно того, что такое EJB или как они работают, мы уже опубликовали вступительную статью на эту тему здесь .

2. Настройка EJB

Нам нужно будет создать наши удаленные интерфейсы и наши реализации EJB. Чтобы сделать их пригодными для использования, нам также понадобится контейнер для хранения бобов и управления ими.

2.1. Удаленные интерфейсы EJB

Давайте начнем с определения двух очень простых компонентов — одного без гражданства и одного с сохранением состояния.

Начнем с их интерфейсов:

@Remote
public interface HelloStatefulWorld {
    int howManyTimes();
    String getHelloWorld();
}

@Remote
public interface HelloStatelessWorld {
    String getHelloWorld();
}

2.2. Реализация EJB

Теперь давайте реализуем наши удаленные интерфейсы EJB:

@Stateful(name = "HelloStatefulWorld")
public class HelloStatefulWorldBean implements HelloStatefulWorld {

    private int howManyTimes = 0;

    public int howManyTimes() {
        return howManyTimes;
    }

    public String getHelloWorld() {
        howManyTimes++;
        return "Hello Stateful World";
    }
}

@Stateless(name = "HelloStatelessWorld")
public class HelloStatelessWorldBean implements HelloStatelessWorld {

    public String getHelloWorld() {
        return "Hello Stateless World!";
    }
}

Если бобы с состоянием и без состояния звучат незнакомо, эта вводная статья может пригодиться.

2.3. Контейнер EJB

Мы можем запустить наш код в любом контейнере JEE, но для практических целей мы будем использовать Wildfly и плагин cargo Maven, чтобы сделать тяжелую работу за нас:


    org.codehaus.cargo
    cargo-maven2-plugin
    1.6.1
    
        
            wildfly10x
            
                
                  http://download.jboss.org/wildfly/10.1.0.Final/wildfly-10.1.0.Final.zip
                
            
        
        
            
                127.0.0.1
                standalone-full
                9990
                testUser:admin1234!
            
        
    

2.4. Запуск EJBs

Если они настроены, мы можем запустить контейнер непосредственно из командной строки Maven:

mvn clean package cargo:run -Pwildfly-standalone

Теперь у нас есть рабочий экземпляр Wildfly, размещающий наши бобы. Мы можем подтвердить это строками журнала:

java:global/ejb-remote-for-spring/HelloStatefulWorld!com.baeldung.ejb.tutorial.HelloStatefulWorld
java:app/ejb-remote-for-spring/HelloStatefulWorld!com.baeldung.ejb.tutorial.HelloStatefulWorld
java:module/HelloStatefulWorld!com.baeldung.ejb.tutorial.HelloStatefulWorld
java:jboss/exported/ejb-remote-for-spring/HelloStatefulWorld!com.baeldung.ejb.tutorial.HelloStatefulWorld
java:global/ejb-remote-for-spring/HelloStatefulWorld
java:app/ejb-remote-for-spring/HelloStatefulWorld
java:module/HelloStatefulWorld

java:global/ejb-remote-for-spring/HelloStatelessWorld!com.baeldung.ejb.tutorial.HelloStatelessWorld
java:app/ejb-remote-for-spring/HelloStatelessWorld!com.baeldung.ejb.tutorial.HelloStatelessWorld
java:module/HelloStatelessWorld!com.baeldung.ejb.tutorial.HelloStatelessWorld
java:jboss/exported/ejb-remote-for-spring/HelloStatelessWorld!com.baeldung.ejb.tutorial.HelloStatelessWorld
java:global/ejb-remote-for-spring/HelloStatelessWorld
java:app/ejb-remote-for-spring/HelloStatelessWorld
java:module/HelloStatelessWorld

3. Установка пружины

Теперь, когда наш контейнер JEE запущен и запущен, а наши EJBS развернуты, мы можем запустить наше приложение Spring. Мы будем использовать spring-boot-web , чтобы упростить тестирование вручную, но это не обязательно для удаленного вызова.

3.1. Зависимости Maven

Чтобы иметь возможность подключиться к удаленным EJBS, нам понадобится клиент Wildfly EJB библиотека и наш удаленный интерфейс:


    org.wildfly
    wildfly-ejb-client-bom
    10.1.0.Final
    pom


    com.baeldung.spring.ejb
    ejb-remote-for-spring
    1.0.1
    ejb

Последнюю версию wildfly-ejb-client-bom можно найти здесь .

3.2. Контекст Стратегии именования

С помощью этих зависимостей в пути к классу мы можем создать экземпляр javax.naming.Контекст для поиска наших удаленных бобов . Мы создадим это как весенний боб, чтобы мы могли автоматически подключать его, когда нам это нужно:

@Bean   
public Context context() throws NamingException {
    Properties jndiProps = new Properties();
    jndiProps.put("java.naming.factory.initial", 
      "org.jboss.naming.remote.client.InitialContextFactory");
    jndiProps.put("jboss.naming.client.ejb.context", true);
    jndiProps.put("java.naming.provider.url", 
      "http-remoting://localhost:8080");
    return new InitialContext(jndiProps);
}

Свойства необходимы для информирования как удаленного URL , так и контекста стратегии именования .

3.3. Шаблон JNDI

Прежде чем мы сможем подключить наши удаленные бобы к пружинному контейнеру, нам нужно знать, как до них добраться. Для этого мы будем использовать их привязки JNDI. Давайте посмотрим стандартный шаблон для этих привязок:

${appName}/${moduleName}/${distinctName}/${beanName}!${viewClassName}

Имейте в виду, что, поскольку мы развернули простой jar вместо ear и явно не настроили имя, у нас нет AppName и distinctName . Более подробная информация содержится в нашей статье EJB Intro на случай, если что-то покажется странным.

Мы будем использовать этот шаблон, чтобы привязать наши удаленные бобы к нашим весенним.

3.4. Создание Наших Весенних Бобов

Чтобы добраться до наших EJBS, мы будем использовать вышеупомянутый JNDI. Помните строки журнала, которые мы использовали, чтобы проверить, были ли развернуты наши корпоративные компоненты?

Теперь мы увидим, что эта информация используется:

@Bean
public HelloStatelessWorld helloStatelessWorld(Context context) 
  throws NamingException {
 
    return (HelloStatelessWorld) 
      context.lookup(this.getFullName(HelloStatelessWorld.class));
}
@Bean
public HelloStatefulWorld helloStatefulWorld(Context context) 
  throws NamingException {
 
    return (HelloStatefulWorld) 
      context.lookup(this.getFullName(HelloStatefulWorld.class));
}
private String getFullName(Class classType) {
    String moduleName = "ejb-remote-for-spring/";
    String beanName = classType.getSimpleName();
    String viewClassName = classType.getName();
    return moduleName + beanName + "!" + viewClassName;
}

Мы должны быть очень осторожны с правильной полной привязкой JNDI , иначе контекст не сможет достичь удаленного EJB и создать необходимую базовую инфраструктуру.

Имейте в виду, что метод lookup from Context вызовет исключение NamingException в случае, если он не найдет нужный вам компонент.

4. Интеграция

Имея все на месте, мы можем ввести наши бобы в контроллер , чтобы проверить, правильна ли проводка:

@RestController
public class HomeEndpoint {
 
    // ...
 
    @GetMapping("/stateless")
    public String getStateless() {
        return helloStatelessWorld.getHelloWorld();
    }
    
    @GetMapping("/stateful")
    public String getStateful() {
        return helloStatefulWorld.getHelloWorld()
          + " called " + helloStatefulWorld.howManyTimes() + " times";
    }
}

Давайте запустим наш весенний сервер и проверим некоторые журналы. Мы увидим следующую строку, указывающую на то, что все в порядке:

EJBCLIENT000013: Successful version handshake completed

Теперь давайте проверим наш боб без гражданства. Мы можем попробовать некоторые команды curl , чтобы убедиться, что они работают должным образом:

curl http://localhost:8081/stateless
Hello Stateless World!

И давайте проверим состояние:

curl http://localhost:8081/stateful
Hello Stateful World called 1 times

curl http://localhost:8081/stateful
Hello Stateful World called 2 times

5. Заключение

В этой статье мы узнали, как интегрировать Spring в EJB и выполнять удаленные вызовы контейнера JEE. Мы создали два удаленных интерфейса EJB, и мы смогли вызвать их с помощью Spring Beans прозрачным способом.

Несмотря на широкое распространение Spring, EJB по-прежнему популярны в корпоративных средах, и в этом кратком примере мы показали, что можно использовать как распределенные преимущества Jakarta EE, так и простоту использования приложений Spring.

Как всегда, код можно найти на GitHub .