EJB

Enterprice java bean

Компоненты EJB:
1. session bean - используется для описании бизнес-логики.
             Существует 3 подвида:
           1. Stateless - не хранит состояние бина.
           2. Stateful - хранит состояние бина между вызовами для отдельного клиента. Пример, корзина в интернет-магазина.
           3. Singleton - хранит состояние на протяжение работы всего приложение


2. message-driven bean - также бизнес-логика (JMS). Коммуникация между компонентами, использующими JMS, асинхронна (процедура не дожидается ответа на своё сообщение) и независима от исполнения компонентов. MDB - stateless.
JMS поддерживает две модели обмена сообщениями: «от пункта к пункту» и «издатель-подписчик».
Модель «от пункта к пункту» QUEUE (Point-to-Point) характеризуется следующим:
  • Каждое сообщение имеет только одного получателя
  • Сообщение попадает в «почтовый ящик», или «очередь» адресата и может быть прочитано когда угодно. Если адресат не работал в момент отсылки сообщения, сообщение не пропадёт.
  • После получения сообщения получатель посылает извещение.
Модель «издатель-подписчик» TOPIC (Publish-subscribe) характеризуется следующим:
  • Подписчик подписывается на определённую «тему»
  • Издатель публикует своё сообщение. Его получают все подписчики этой темы
  • Получатель должен работать и быть подписан в момент отправки сообщения
@MessageDriven( //имя topic, на который подписан бин mappedName="jms/TutorialTopic", name = "ExampleMDB") public class MDBExample implements MessageListener{ //метод, вызываемый при получении нового сообщения @Override public void onMessage(Message msg) { try { TextMessage message = (TextMessage)msg; //считываем свойство из соответствующего поля, заданное вручную в consumer System.out.println("FROM MDB - client type IS " + message.getStringProperty("clientType")); //считываем само сообщение System.out.println("FROM MDB - payload IS" + message.getText()); } catch (JMSException ex) { ex.printStackTrace(); } } }
В onMessage метод добавляется необходимая бизнес логика, в зависимости от типа сообщения, его содержания и тд.
3. entities - для хранения данных. Pojo обьект промапленный таблицей.
//mark it entity using Entity annotation 
//map table name using Table annoation
@Entity
@Table(name="books")
public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book(){        
   }

   //mark id as primary key with autogenerated value
   //map database column id with id field
   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }
   ... 
 Используется вместе с JPA. Маппинг сущностей  и отображение их в базе данных.
EntityManager - API для CRUD
 @Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
 
   //pass persistence unit to entityManager.
   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {        
      return entityManager.createQuery("From Books").getResultList();
   }
   ...
}
Persistence unit (persistence.xml) - свойства для перзистентности.
+ JPQL.

Встраивание POJO класса в сущность.

@Embeddable
public class Publisher implements Serializable{
   private String name;
   private String address;
   ...
}
The above class can be embedded using @Embedded annotation
@Entity
public class Book implements Serializable{
   private int id;
   private String name;
   private Publisher publisher;
   ...
   @Embedded
   @AttributeOverrides({
   @AttributeOverride(name = "name", 
                      column = @Column(name = "PUBLISHER")),
   @AttributeOverride(name = "address", 
                      column = @Column(name = "PUBLISHER_ADDRESS"))
   })
   public Publisher getPublisher() {
      return publisher;
   }
   ...
}
EAGER VS LAZY FETCH
public class University {
 private String id;
 private String name;
 private String address;
 private List<Student> students;

 // setters and getters
}
Now when you load a University from the database, JPA loads its id, name, and address fields for you. But you have two options for students: to load it together with the rest of the fields (i.e. eagerly) or to load it on-demand (i.e. lazily) when you call the university's getStudents() method.
Пример JPQL


package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean(){
   }

   @PersistenceContext(unitName="EntityEjbPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      //create an ejbql expression
      String ejbQL = "From Book b where b.name like ?1";
      //create query
      Query query = entityManager.createQuery(ejbQL);
      //substitute parameter.
      query.setParameter(1, "%test%");   
      //execute the query
      return query.getResultList();
   }   
}
Какие аннотации могут быть?
  • Stateless - говорит контейнеру, что класс будет stateless session bean. Для него контейнер обеспечит безопасность потоков и менеджмент транзакций. Дополнительно, вы можете добавить другие свойства, например прозрачное управление безопасностью и перехватчики событий;
  • Local - относится к интерфейсу и говорит, что bean реализующий интерфейс доступен локально (если в одной и той же среде JVM)
  • Remote - относится к интерфейсу и говорит, что bean доступен через RMI (Remote Method Invocation) (в другой среде JVM)
  • EJB - применятеся в коде, где мы используем bean.
  • Stateful - говорит контейнеру, что класс будет stateful session bean.
  • Entity - говорит контейнеру, что класс будет сущностью БД
  • Table(name="...") - указывает таблицу для маппинга
  • IdColumn - параметры маппинга
  • WebService - говорит, что интерфейс или класс будет представлять вэб-сервис.
  • и много-много других..
  • @EJB - used to inject other EJB reference.
  • @Resource - used to inject datasource or singleton services like sessionContext, timerService etc.
Условия создания session bean
В качестве session bean может выступать обычный класс Java удовлетворяющий следующим условиям:
  • иметь как минимум один метод
  • не должен быть абстрактным
  • иметь конструктор по-умолчанию
  • методы не должны начинаться с "ejb" (например ejbCreate, ejbDoSomething)
Для stateful-бинов существует еще одно условие: свойства класса должны быть объявлены примитивами или реализовывать интерфейс Serializable. 

Методы жизненного цикла EJB
У stateless и MDB бинов существует 2 события жизненного цикла, которые мы можем перехватить: создание и удаление бина. Метод, который будет вызываться сразу после создании бина помечается аннотацией javax.annotation.PostConstruct, а перед его удалением - javax.annotation.PreDestroy. Stateful бины обладают помимо рассмотреных выше еще 2 событиями: при активации (javax.ejb.PostActivate) и при деактивации (javax.ejb.PrePassivate).

Особенности stateless и stateful бинов
Контейнер помещает экземпляры stateless-бинов в общее хранилище и множество клиентов могут использовать один экземпляр бина. (пул обьектов бинов) В отличии от stateless stateful бины инстанцируются для каждого пользователя отдельно.



Thread

Два основных способа создания потоков:
1. Наследование класса Thread.
2. Реализация интерфейса Runnable.

public class MyClass implements Runnable{

@Override
public void run(){
System.out.println("Thread is running");
}

public static void main (String[]  args){
MyClass myClass = new MyClass();

Thread thread = new Thread(myClass);
thread.start();
}
}


  1. New - когда создан экземпляр Thread, но метод start() еще не запущен. Поток не считается живым.
  2. Runnable - впервые поток принимает данный статус, после того как запускается метод start(). Далее планировщик потоков принимает решение переводить его в статус Running или другой.
  3. Running - это выполнение самого поток, метода run()
  4. Waiting - поток в режиме ожидания.
  5. Sleeping - поток временно уснул, метод Thread.sleep(long millis)
  6. Blocking - заблокирован в ожидании ресурсов, например, I/O или Object Lock.
  7. Dead - поток завершил свою роботу, нельзя запустить снова. Будет Runtime exception.
Метод Start() не можна вызывать два раза. Если будет вызван второй раз, то будет IllegalThreadStateException.


Методы java.lang.Thread:
  • public static void sleep(long millis) throws InterruptedException
  • public static void yield() - переводит текущий поток з статуса Running в статус Runnable.
  • public final void join() throws InterruptedException - переводит текущий поток в статус блок. t.join() - значит, что сначала выполнится поток T, а потом уже только main поток.
  • public final void setPriority(int newPriority) - от 1 до 10
Методы java.lang.Object  необходимые для многопоточности, Вызываются только в синхронизированном контексте:
  • public final void wait() throws InterruptedException  - ждать пока не вызвется notify() или notofyAll(). Когда поток ждет, он временно отпускает лок. wait() вызывается в лока. 
  • public final void notify()
  • public final void notifyAll()
Пример синхронизации статического метода. Используется глобальный лок MyClass.class



Inner classes

Внешний класс имеет доступ к private полям внутреннего.
Виды внутренних классов:

  • статические (nested - вложенные)
  • локальные(внутри метода) - могут создаваться только внутри метода, имеют доступ ко всем свойствам внешнего класса. Но не имеет доступа к локальным переменным самого метода (кроме final).
  • анонимные

Вызов внутреннего класс извне:
MyOuter.MyInner inner = new MyOuter().new MyInner();


Анонимный класс (extends)

метод sizzle не видно, из-за того что ссылка p полиморфная, а в родительском классе нет такого метода.

Nested class

Generics

List<String> list = new ArrayList<>();
Коллекция может принимать только строки, иначе будет ошибка компиляции (type-safe).

List<Number> list - new ArrayList<Integer>(); - compile error

Parent[] myArray = new Chile[3]; -  но для массива работает.

public void addAnimal(List<? extends Animal> list) - метод может принимать полиморфные элементы списка. Все, что наследуется от Animal.

public void addAnimal(List<? super Dog> list) - метод может принимать полиморфные элементы списка. Все супер классы для Dog (Object, Animal).

List<?> list = new ArrayList<Integer>(); - список может быть абсолютно любым.

public void addAnimal(List<Object> list) - метод может принимать ТОЛЬКО List<Object>.

Создание своих дженериков:
public class MyClass<T, X>  - класс с двумя дженериками

public <T> add(T t) - void метод с параметром, который обьязательно нужно обьявлять перед методом (если не указан в классе)

Iterator

Два метода:
boolean hasNext() - есть ли еще один элемент.
Object next() - возвращает элемент и двигается к следующему.

List<Dog> listDog = new ArrayList<>();
Iterator<Dog> iter = listDog.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}

Comparator and Comparable

Comparator и Comparable - интерфейсы которые используются при сортировки.

Collection

List - список построен по индексах.
ArrayList - похож по принципу на обычный массив, только с возможностью добавления и удаления элементов. Предоставляет одинаковый по времени доступ ко всем элементам. Но плох при удаление или вставки элементов в центр списка.

Vector - такой же как ArrayList, только у него все методы синхронизированы из-за чего он медленней.

LinkedList - каждый элемент имеет по две ссылки на предыдущий и следующий элементы. Работает быстро если нужно вставить или удалить элемент. Но доступ к определенном элементу медленней чем в ArrayList.

Set - множество, где каждый элемент должен быть уникален. 
HashSet - не сортированное множество. HASHCODE

LinkedHashSet - упорядоченное (в том порядке в котором были вставлены элементы) множество, где каждый элемент имеет две ссылки на предыдущий и следующий элементы.

TreeSet - отсортированное множество в натуральном порядке, но можно изменять сортировку в конструкторе переопределя Comparator или Comparable.

Map - список с элементами типа уникальный ключ - значение.
HashMap - не сортированная карта. Может иметь один null ключ и много null value.

HashTable - аналогичен HashMap, только методы синхронизированы. Еще одно отличие value и key никогда не может быть NULL.

LinkedHashMap - быстрее работает перебор элементов, но вставка и удаление медленнее.

TreeMap - отсортированная карта.

Queue -принцип FIFO, первый зашел, первый вышел.

PriorityQueue - элементы упорядочены и отсортированы ( в натурально порядке).
Poll() - возвращает элемент с очереди с самым большим приоритетом (первый по сортировке) и удаляет этот элемент (делает его null).
offer() - вставляет элемент в очередь.
peek() - возвращает элемент с самым большим приоритетом.