08.05.2012

JavaEE: EJB компонент на Jboss 7.1.

Кратко об Enterprise JavaBeans (EJB). EJB компонент представляет собой класс или набор классов, в которых используются специальные аннотации. Каждый EJB компонент выполняется на сервере приложений, и получить доступ к функциональности компонента можно различными способами: из JSP или JSF страницы, из сервлета, с помощью веб-сервиса, из другого EJB компонента, из апплета, а также из обычного приложения JavaSE.
 
 
Технология EJB предоставляет множество возможностей и позволяет создавать гибкие и надежные системы. EJB компоненты могут использоваться для распределенных вычислений; для поддержки сохранности данных -  когда данные должны быть надежно защищены, даже после завершения клиентского приложения; для ограничения доступа к данным; для различных способов удаленного доступа; для поддержки автоматизированной установки приложений на сервер и пр. EJB компоненты бывают трех видов:
 
1) Сессионные (Session Beans) - компоненты, которые не сохраняют состояние после завершения сессии.
2) Управляемые сообщениями (Message Driven Beans) - компоненты, которые реагируют на события в системе.
3) Объектные (Entity Bean) - компоненты, состояние которых может быть сохранено в базе данных, сейчас в спецификации Java Persistence API

Сессионные компоненты, именно такие мы сейчас и будем создавать,  разделяются на два вида:

  • Без состояния (Stateless) - просто говоря, единственная возможность такого компонента это вызов его метода с его локальными данными. В таком компоненте, например, нельзя создать поле для сохранения чего-либо.   
  • С поддержкой текущего состояния сессии (Stateful) - такой компонент ведет себя как полноценный класс, в котором можно создать поля и работать с ними в течение сесси.  

Вызов метода EJB компонента, который выполнится на сервере, с виду ничем не отличается от вызова метода обычного объекта, различие видно в способе создания самого объекта. Для получение доступа к EJB есть два способа: Dependency Injection (DI) и Java Naming and Directory Service (JNDI). В примере создадим два сессионных EJB компонента - без состояния и с поддержкой текущего состояния сессии. Клиентом будет обычное Java приложение, из чего следует, что для доступа к EJB будем использовать JNDI.

Пример создания EJB компонентов и клиента.

В примере будет использоваться Eclipse IDE (Indigo), сервер приложений - Jboss 7.1.1 Final, который поддерживает спецификацию EJB 3.1. По поводу установки Jboss 7 и Eclipse можно посмотреть здесь. Итак, создаем новый проект (File > New > EJB Project), добавляем интерфейс и класс Stateless EJB компонента:

package packg;

public interface StatelessEjb {
  public String sayHi(String name);
}
package packg;
import javax.ejb.Stateless;
import javax.ejb.Remote;

@Stateless
@Remote(StatelessEjb.class)
public class StatelessEjbBean 
  implements StatelessEjb {

  @Override
  public String sayHi(String name){
   return "Hi " + name + "!";
  }
}

Теперь создадим интерфейс и класс для Stateful компонента:

package packg;

public interface StatefulEjb {
  public void put(String value);
  public String pop();
}
package packg;
import java.util.Stack;
import javax.ejb.Stateful;
import javax.ejb.Remote;

@Stateful
@Remote(StatefulEjb.class)
public class StatefulEjbBean implements StatefulEjb {
  private Stack<String> stack;

  public StatefulEjbBean(){
   stack = new Stack<String>();
  }

  @Override
  public void put(String value) {
   stack.push(value);
  }

  @Override
  public String pop() {
   return stack.pop();
  }
}

Как можно видеть, все что здесь нужно, это аннотации @Stateless, @Statefull и @Remote. На этом можно переходить к написанию клиентского приложения, что будет не намного сложнее. Создаем Java проект и добавляем в него интерфейсы StatelessEjb и StatefulEjb. Сам клиент:

public class Main {

    private static Logger log = Logger.getLogger(Main.class);

    public static void main(String[] args) {

        try {

            Context context = getInitialContext();
            String nameStateless =
            "ejb:/testEJB/StatelessEjbBean!packg.StatelessEjb";
            StatelessEjb statelessBean = (StatelessEjb) context
                    .lookup(nameStateless);

            String nameStateful =
            "ejb:/testEJB/StatefulEjbBean!packg.StatefulEjb?stateful";
            StatefulEjb statefulBean = (StatefulEjb) context
                    .lookup(nameStateful);

            log.info("Вызов метода sayHi (stateless EJB)\n"
                    + statelessBean.sayHi("Alex"));
           
            statefulBean.put("here we go");
            log.info("Вызов метода pop (stateful EJB)\n" + statefulBean.pop());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Context getInitialContext()
            throws javax.naming.NamingException {
       
        Hashtable<String, String> prop = new Hashtable<String, String>();
        prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        return new javax.naming.InitialContext(prop);
       
    }
}

По сравнению с ранними версиями Jboss, в Jboss 7 доступ к EJB с помощью JNDI изменился. Вместо того, чтобы просто написать Context context = new InitialContext(), мы используем getInitialContext(). Раньше иcпользовался конфигурационный файл jndi.properties, а теперь нужно создавать файл jboss-ejb-client.properties (должен находиться в src):

remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=4447
Здесь указывается адрес и порт сервера, на котором выполняется компонент. Имя, по которому доступен EJB компонент, присваивается сервером, для доступа к Stateless компоненту используется такой синтаксис:
 
ejb:/<module-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>
 
А для доступа к Stateful такой:
 
ejb:/<module-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>?stateful
 
Единственное что осталось сделать, для того чтобы клиент заработал - добавить в проект необходимые библиотеки, которые можно найти в каталоге установки Jboss: 
 
modules\org\jboss\ejb-client\main\jboss-ejb-client-1.0.5.Final.jar modules\org\jboss\logging\main\jboss-logging-3.1.0.GA.jar
modules\org\jboss\logmanager\main\jboss-logmanager-1.2.2.GA.jar modules\javax\ejb\api\main\jboss-ejb-api_3.1_spec-1.0.1.Final.jar
modules\org\jboss\marshalling\main\jboss-marshalling-1.3.11.GA.jar modules\org\jboss\remoting3\main\jboss-remoting-3.2.3.GA.jar
modules\org\jboss\xnio\main\xnio-api-3.0.3.GA.jar
modules\org\jboss\sasl\main\jboss-sasl-1.0.0.Final.jar
modules\javax\transaction\api\main\jboss-transaction-api_1.1_spec-1.0.0.Final.jar
modules\org\jboss\xnio\nio\main\xnio-nio-3.0.3.GA.jar
modules\org\jboss\marshalling\river\main\jboss-marshalling-river-1.3.11.GA.jar bin\client\jboss-client.jar
modules\org\apache\log4j\main\log4j-1.2.16.jar  
 
В итоге, структура проекта клиентского приложения должна выглядеть примерно так:
 
 
Все готово, теперь можно запустить сервер, предварительно добавив на него EJB проект, и выполнить клиент. Очень хорошее руководство по EJB - EJB 3.1 Cookbook (eng).
Скачать пример


Теги: programming java javaEE

comments powered by Disqus