Guia de Integração para Spring e EJB

Guia de Integração para Spring e EJB

1. Visão geral

Neste artigo, mostraremos comointegrate Spring and remote Enterprise Java Beans (EJB).

Para fazer isso, criaremos alguns EJBs e as interfaces remotas necessárias e, em seguida, os executaremos dentro de um contêiner JEE. Depois disso, iniciaremos nosso aplicativo Spring e, usando as interfaces remotas, instanciaremos nossos beans para que possam executar chamadas remotas.

Se houver alguma dúvida sobre o que são ou como funcionam os EJBs, já publicamos um artigo introdutório sobre o temahere.

2. Configuração EJB

Precisamos criar nossas interfaces remotas e nossas implementações EJB. Para torná-los utilizáveis, também precisaremos de um contêiner para armazenar e gerenciar os grãos.

2.1. Interfaces remotas EJB

Vamos começar definindo dois beans muito simples - um sem estado e outro com estado.

Começaremos com suas interfaces:

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

2.2. Implementação EJB

Agora, vamos implementar nossas interfaces EJB remotas:

@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!";
    }
}

Se os beans com e sem estado parecerem desconhecidos,this intro article pode ser útil.

2.3. Contêiner EJB

Podemos executar nosso código em qualquer contêiner JEE, mas para fins práticos, usaremos Wildfly e o plug-incargo Maven para fazer o trabalho pesado para nós:


    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. Executando os EJBs

Com estes configurados, podemos executar o contêiner diretamente da linha de comando do Maven:

mvn clean package cargo:run -Pwildfly-standalone

Agora temos uma instância de trabalho do Wildfly hospedando nossos beans. Podemos confirmar isso pelas linhas de log:

java:global/ejb-remote-for-spring/HelloStatefulWorld!com.example.ejb.tutorial.HelloStatefulWorld
java:app/ejb-remote-for-spring/HelloStatefulWorld!com.example.ejb.tutorial.HelloStatefulWorld
java:module/HelloStatefulWorld!com.example.ejb.tutorial.HelloStatefulWorld
java:jboss/exported/ejb-remote-for-spring/HelloStatefulWorld!com.example.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.example.ejb.tutorial.HelloStatelessWorld
java:app/ejb-remote-for-spring/HelloStatelessWorld!com.example.ejb.tutorial.HelloStatelessWorld
java:module/HelloStatelessWorld!com.example.ejb.tutorial.HelloStatelessWorld
java:jboss/exported/ejb-remote-for-spring/HelloStatelessWorld!com.example.ejb.tutorial.HelloStatelessWorld
java:global/ejb-remote-for-spring/HelloStatelessWorld
java:app/ejb-remote-for-spring/HelloStatelessWorld
java:module/HelloStatelessWorld

3. Configuração da Primavera

Agora que temos nosso contêiner JEE em funcionamento e nossos EJBs implantados, podemos iniciar nosso aplicativo Spring. Usaremosspring-boot-web para facilitar o teste manualmente, mas não é obrigatório para a chamada remota.

3.1. Dependências do Maven

Para poder se conectar aos EJBs remotos, precisaremos da bibliotecaWildfly EJB Client e de nossa interface remota:


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


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

A última versão dewildfly-ejb-client-bom pode ser encontradahere.

3.2. Contexto da Estratégia de Nomenclatura

Com essas dependências no caminho de classe, podemosinstantiate a javax.naming.Context to do the lookup of our remote beans. Vamos criar isso como um Spring Bean para que possamos fazer o autowire quando precisarmos:

@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);
}

As propriedades são necessárias parainform both the remote URL and the naming strategy context.

3.3. Padrão JNDI

Antes de conectarmos nossos beans remotos dentro do contêiner Spring, precisamos saber como alcançá-los. Para isso, usaremos suas ligações JNDI. Vamos ver o padrão padrão para essas ligações:

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

Lembre-se de quesince we deployed a simple jar instead of an ear and didn’t explicitly set up a name, we don’t have an appName and a distinctName. Existem mais detalhes em nossoEJB Intro article caso algo pareça estranho.

Usaremos esse padrão para vincular nossos beans remotos aos do Spring.

3.4. Construindo nosso Spring Beans

To reach our EJBs, we’ll use the aforementioned JNDI. Lembra das linhas de log que usamos para verificar se nossos enterprise beans foram implantados?

Veremos essas informações em uso agora:

@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;
}

We need to be very careful about the correct full JNDI binding, ou o contexto não será capaz de alcançar o EJB remoto e criar a infraestrutura subjacente necessária.

Tenha em mente que o métodolookup deContext lançará umNamingException caso não encontre o bean que você está solicitando.

4. Integração

Com tudo no lugar, podemosinject our beans in a controller, para que possamos testar se a fiação está correta:

@RestController
public class HomeEndpoint {

    // ...

    @GetMapping("/stateless")
    public String getStateless() {
        return helloStatelessWorld.getHelloWorld();
    }

    @GetMapping("/stateful")
    public String getStateful() {
        return helloStatefulWorld.getHelloWorld()
          + " called " + helloStatefulWorld.howManyTimes() + " times";
    }
}

Vamos iniciar nosso servidor Spring e verificar alguns logs. Veremos a seguinte linha, indicando que está tudo bem:

EJBCLIENT000013: Successful version handshake completed

Agora, vamos testar nosso bean sem estado. Podemos tentar alguns comandoscurl para verificar se eles estão operando conforme o esperado:

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

E vamos verificar nosso estado:

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

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

5. Conclusão

Neste artigo, aprendemos como integrar o Spring ao EJB e fazer chamadas remotas para o contêiner JEE. Criamos duas interfaces EJB remotas e conseguimos chamar os usuários do Spring Beans de maneira transparente.

Mesmo que o Spring seja amplamente adotado, os EJBs ainda são populares em ambientes empresariais e, neste exemplo rápido, mostramos que é possível fazer uso dos ganhos distribuídos do JavaEE e da facilidade de uso dos aplicativos Spring.

Como sempre, o código pode ser encontradoover on GitHub.