Enterprise JavaBeans — Википедия
Enterprise JavaBeans (также часто употребляется в виде аббревиатуры EJB) — спецификация технологии написания и поддержки серверных компонентов, содержащих бизнес-логику. Является частью Java EE.
Эта технология обычно применяется, когда бизнес-логика требует как минимум один из следующих сервисов, а часто все из них:
- поддержка сохранности данных (persistence); данные должны быть в сохранности даже после остановки программы, чаще всего достигается с помощью использования базы данных
- поддержка распределённых транзакций
- поддержка параллельного изменения данных и многопоточность
- поддержка событий
- поддержка именования и каталогов (JNDI)
- безопасность и ограничение доступа к данным
- поддержка автоматизированной установки на сервер приложений
- удалённый доступ
Каждый EJB-компонент является набором Java-классов со строго регламентированными правилами именования методов (верно для EJB 2.0, в EJB 3.0 за счет использования аннотаций выбор имён свободный). Бывают трёх основных типов:
- объектные (Entity Bean) — перенесены в спецификацию Java Persistence API
- сессионные (Session Beans), которые бывают
- stateless (без состояния)
- stateful (с поддержкой текущего состояния сессии)
- singleton (один объект на все приложение; начиная с версии 3.1)
- управляемые сообщениями (Message Driven Beans) — их логика является реакцией на события в системе
Пример Entity Bean
[править | править код]package org.test.entity; import java.io.Serializable; import java.util.Date; import javax.persistence.*; import javax.validation.constraints.Size; import org.test.entity.listener.GalleryListener; @Entity @EntityListeners({GalleryListener.class}) @Table(name = "gallery", uniqueConstraints = { @UniqueConstraint(columnNames = {"id"}) } ) @NamedQueries({ @NamedQuery(name = Gallery.QUERY_FIND_ALL, query = "SELECT g FROM Gallery g ORDER BY g.name ASC"), @NamedQuery(name = Gallery.QUERY_FIND_BY_NAME, query = "SELECT g FROM Gallery g WHERE g.name = :name") }) public class Gallery implements Serializable { private static final long serialVersionUID = 1L; public static final String QUERY_FIND_ALL = "Gallery.findAll"; public static final String QUERY_FIND_BY_NAME = "Gallery.findByName"; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id; @Size(max = 100) @Column(name = "name", length = 100) private String name; @Column(name = "created_at") @Temporal(TemporalType.TIMESTAMP) private Date createdAt; public Gallery() { } public Gallery(String name) { this.name = name; } public Date getCreatedAt() { return createdAt; } public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Gallery other = (Gallery) obj; if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) { return false; } return true; } @Override public int hashCode() { int hash = 7; hash = 47 * hash + (this.id != null ? this.id.hashCode() : 0); return hash; } }
Пример Entity Bean Listener
[править | править код]package org.test.entity.listener; import java.util.Date; import javax.persistence.PrePersist; import org.test.entity.Gallery; public class GalleryListener { @PrePersist public void prePersist(Gallery gallery) { gallery.setCreatedAt(new Date()); } }
Пример Session Bean - Stateless EAO (Entity Access Object)
[править | править код]package org.test.eao; import java.util.List; import javax.ejb.LocalBean; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.test.entity.Gallery; @Stateless @LocalBean public class GalleryEAO extends AbstractEAO<Gallery> { @PersistenceContext(unitName = "PersistenceUnit") private EntityManager entityManager; public GalleryEAO() { super(Gallery.class); } @Override protected EntityManager getEntityManager() { return entityManager; } @TransactionAttribute(TransactionAttributeType.SUPPORTS) public List<Gallery> findAll() { return namedQuery(Gallery.QUERY_FIND_ALL).getResultList(); } @TransactionAttribute(TransactionAttributeType.SUPPORTS) public Gallery findByName(String name) { return namedQuery(Gallery.QUERY_FIND_BY_NAME) .setParameter("name", name) .getSingleResult(); } }
Пример Abstract EAO (Entity Access Object)
[править | править код]package org.test.eao; import java.io.Serializable; import javax.persistence.EntityManager; import javax.persistence.Query; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; public abstract class AbstractEAO<T extends Serializable> { protected abstract EntityManager getEntityManager(); private Class<T> entityClass; public Class<T> getEntityClass() { return entityClass; } public AbstractEAO(Class<T> entityClass) { this.entityClass = entityClass; } public void persist(T entity) { getEntityManager().persist(entity); } public void merge(T entity) { getEntityManager().merge(entity); } public void remove(T entity) { if (entity != null) { getEntityManager().remove(entity); } } public void remove(Object id) { T entity = (T) getEntityManager().find(entityClass, id); remove(entity); } public T find(Object id) { return getEntityManager().find(entityClass, id); } public void refresh(T entity) { getEntityManager().refresh(entity); } public TypedQuery<T> namedQuery(String queryName) { return getEntityManager().createNamedQuery(queryName, entityClass); } public TypedQuery<T> query(String queryString) { return getEntityManager().createQuery(queryString, entityClass); } public long count() { CriteriaQuery criteriaQuery = getEntityManager().getCriteriaBuilder().createQuery(); Root<T> root = criteriaQuery.from(entityClass); criteriaQuery.select(getEntityManager().getCriteriaBuilder().count(root)); Query query = getEntityManager().createQuery(criteriaQuery); return ((Long) query.getSingleResult()).longValue(); } }
Пример Session Bean (Stateless) - Gallery Facade
[править | править код]package org.test.facade; import java.util.List; import javax.ejb.*; import org.test.eao.GalleryEAO; import org.test.entity.Gallery; import org.test.exception.GalleryAlreadyExistsException; import org.test.exception.GalleryNotFoundException; @Stateless @LocalBean public class GalleryFacade { @Inject private GalleryEAO galleryEAO; @TransactionAttribute(TransactionAttributeType.SUPPORTS) public Gallery findById(Long id) throws GalleryNotFoundException { Gallery gallery = galleryEAO.find(id); if (gallery == null) throw new GalleryNotFoundException("Gallery not found"); return gallery; } @TransactionAttribute(TransactionAttributeType.SUPPORTS) public List<Gallery> findAll() { return galleryEAO.findAll(); } @TransactionAttribute(TransactionAttributeType.REQUIRED) public void create(String name) throws GalleryAlreadyExistsException { if (galleryEAO.findByName(name) != null) throw new GalleryAlreadyExistsException("Gallery already exists", name); Gallery gallery = new Gallery(name); galleryEAO.persist(gallery); } @TransactionAttribute(TransactionAttributeType.REQUIRED) public void remove(Long id) throws GalleryNotFoundException { Gallery gallery = findById(id); galleryEAO.remove(gallery); } }
Пример Application Exception - GalleryNotFoundException
[править | править код]package org.test.exception; import javax.ejb.ApplicationException; @ApplicationException(rollback=true) public class GalleryNotFoundException extends Exception { public GalleryNotFoundException() { } public GalleryNotFoundException(String message) { super(message); } }
Пример Application Exception - GalleryAlreadyExistsException
[править | править код]package org.test.exception; import javax.ejb.ApplicationException; @ApplicationException(rollback=true) public class GalleryAlreadyExistsException extends Exception { private String name; public GalleryAlreadyExistsException() { } public GalleryAlreadyExistsException(String message, String name) { super(message); this.name = name; } public String getName() { return name; } }
Литература
[править | править код]- Панда Д. EJB 3 в действии. — ДМК Пресс, 2014. — 618 с. — ISBN 978-5-97060-135-8.
Ссылки
[править | править код]- Официальная страница продукта Enterprise JavaBeans на портале Oracle Архивная копия от 10 июня 2011 на Wayback Machine
- Спецификации различных версий Enterprise JavaBeans от SUN
- Краткое введение в технологию Enterprise JavaBeans (rus)(по версии 1.1) Архивная копия от 9 декабря 2007 на Wayback Machine
- Краткое введение в EJB3 Архивная копия от 11 сентября 2016 на Wayback Machine на Linux Format Wiki Архивная копия от 8 января 2014 на Wayback Machine, LinuxFormat 99