EJB

Enterprise JavaBeans

EJB3.1で各メソッドの同時アクセス管理はEJBコンテナが行うため、synchronizedやvolatile等は不要

EJB = POJO + Annotation / XML

※他サイト参照

セッションBeanのライフサイクル

★Callbacks

★セッションBeanモデル

@Stateless

public class MyEjb {

...

}

@EJB

private MyEjb myEjb;

書き方1

import javax.ejb.Local;

@Local

public interface MyLocalEjb {

...

}

import javax.ejb.Remote;

@Remote

public interface MyRemoteEjb {

...

}

@Stateless

public class MyEjb implements MyLocalEjb, MyRemoteEjb {

...

}

★セッションBeanの種類

書き方2

public interface MyLocalEjb {

...

}

public interface MyRemoteEjb {

...

}

@Stateless

@Remote(MyRemoteEjb.class)

@Local(MyLocalEjb.class)

@LocalBean

public class MyEjb implements MyLocalEjb, MyRemoteEjb {

...

}

@Singleton

@LocalBean

public class MyNoInterfaceBean {

...

}

public interface MyService {...}

import javax.ejb.Remote;

import javax.ejb.Stateless;

@Stateless(name = "MyService")

@Remote(MyService.class)

public class MyServiceImpl implements MyService {...}

利用例

@EJB

private MyRemoteEjb myRemoteEjb;

@EJB

private MyLocalEjb myLocalEjb;

@EJB

private MyEjb myEjb;

@Produces

@EJB(lookup = "java:global/xxx/MyService")

private MyService myService;

★Adding contextual data to EJB

方法1 By SessionContext

ContextService.java

方法2 By EJBClientInterceptor (JBoss)

DEMO

★EJB Inheritance

public interface Remote {

void remote();

}

@Stateless

@Remote(Remote.class)

public class SuperclassEJB implements Remote {

public void remote() {

...

}

}

@Stateless

@Remote(Remote.class)

public class SubclassEJB extends SuperclassEJB {

}

●StatelessセッションBean

@Stateless

public class MyEJB {

@PersistenceContext(unitName="testU")

private EntityManager em;

public List<Book> findBooks() {

TypedQuery<Book> query = em.createNamedQuery("findAllBooks", Book.class);

return query.getResultList();

}

public Book createBook(Book book) {

em.persist(book);

return book;

}

}

●StatefulセッションBean

import javax.ejb.Remove;

// 1.時間が経つと、@Removeが付加されたメソッドが実行される

// 2.インスタンスがメモリから削除される

@Stateful

@StatefulTimeout(value=30, unit=TimeUnit.SECONDS)

public class MyEJB {

@Resource

private DataSource ds;

private Connection conn;

private List<Book> cartBooks = new ArrayList<Book>();

@PostConstruct

@PostActivate

private void init() {

conn = ds.getConnection();

}

@PreDestroy

@PrePassivate

private void close() {

conn.close();

}

public void addBook(Book book) {

if (!cartBooks.contains(book)) {

cartBooks.add(book);

}

}

public void removeBook(Book book) {

if (cartBooks.contains(book)) {

cartBooks.remove(book);

}

}

public int getCountOfBooks() {

if (cartBooks == null || cartBooks.isEmpty()) {

return 0;

}

return cartBooks.size();

}

public float getTotal() {

if (cartBooks == null || cartBooks.isEmpty()) {

return 0F;

}

float total = 0F;

for (Book book : cartBooks) {

total += book.getPrice();

}

return total;

}

public void empty() {

cartBooks.clear();

}

@Remove

public void checkout() {

cartBooks.clear();

}

}

●SingletonセッションBean

同時実行・排他制御を参照

EJB版

@Singleton

public class MyEJB {

private Map<Long, Object> cache = new HashMap<Long, Object>();

@PostConstruct

private void init() {

...

}

public void addToCache(long id, Object object) {

if (!cache.containsKey(id)) {

cache.put(id, object);

}

}

public void removeFromCache(long id) {

if (cache.containsKey(id)) {

cache.remove(id);

}

}

public Object getFromCache(long id) {

if (cache.containsKey(id)) {

return cache.get(id);

}

return null;

}

}

Singletonパターン版

public class MyEJB {

private static MyEJB instance = new MyEJB();

private Map<Long, Object> cache = new HashMap<Long, Object>();

private MyEJB(){ }

public static synchronized MyEJB getInstance() {

return instance;

}

// メソッド

}

★EJB 2.1とEJB 3.0の比較

※他サイト参照

★ステートフル・セッションBeanとステートレス・セッションBeanの違い

※他サイト参照