public class CacheEJB {…}

@DependsOn содержит одну или несколько строк, каждая из которых определяет имя целевого одиночного EJB-компонента. В приведенном далее коде показано, как CacheEJB зависит от инициализации CountryCodeEJB и ZipCodeEJB. @DependsOn("CountryCodeEJB", "ZipCodeEJB") дает указание контейнеру позаботиться о том, чтобы CountryCodeEJB и ZipCodeEJB были инициализированы раньше CacheEJB.

@Singleton

public class CountryCodeEJB {…}

@Singleton

public class ZipCodeEJB {…}

@DependsOn("CountryCodeEJB", "ZipCodeEJB")

@Startup

@Singleton

public class CacheEJB {…}

Как видно в этом коде, вы даже можете комбинировать зависимости, когда речь идет об инициализации при запуске. CacheEJB быстро инициализируется при запуске (поскольку снабжен аннотацией @Startup), и, следовательно, CountryCodeEJB и ZipCodeEJB тоже будут инициализированы при запуске, но раньше CacheEJB.

Вы также можете использовать полностью уточненные имена для ссылки на одиночный EJB-объект, упакованный в другой модуль в рамках одного и того же приложения. Допустим, оба CacheEJB и CountryCodeEJB упакованы в рамках одного приложения (в один и тот же файл с расширением. ear), но в разные файлы с расширением. jar (technical.jar и business.jar соответственно). В приведенном далее коде показано, как CacheEJB зависел бы от CountryCodeEJB:

@DependsOn("business.jar#CountryCodeEJB")

@Singleton

public class CacheEJB {…}

Следует отметить, что ссылка такого рода влечет зависимость кода от деталей упаковки (которыми в данном случае являются имена файлов модулей).

<p>Конкурентный доступ</p>

Как вы уже понимаете, имеется единственный экземпляр одиночного сессионного EJB-компонента, который совместно используется множественными клиентами. Таким образом, конкурентный доступ для клиентов разрешается, при этом им можно управлять с помощью аннотации @ConcurrencyManagement на основе двух разных подходов.

• Конкурентный доступ, управляемый контейнером (CMC), — контейнер управляет конкурентным доступом к экземпляру EJB-компонента, исходя из метаданных (аннотации или XML-эквивалента).

• Конкурентный доступ, управляемый EJB-компонентом (BMC), — контейнер разрешает полный конкурентный доступ и возлагает ответственность за синхронизацию на EJB-компонент.

Если не указать, на основе какого подхода должно осуществляться управление доступом, то по умолчанию будет использоваться конкурентный доступ, управляемый контейнером. В случае с одиночным EJB-компонентом может предусматриваться использование либо одного, либо другого вида доступа, но не обоих сразу. Как вы увидите в последующих разделах, аннотацию @AccessTimeout можно применять для запрета конкурентного доступа (иначе говоря, если клиент вызовет бизнес-метод, который уже используется другим клиентом, то конкурентный вызов приведет к генерированию исключения ConcurrentAccessException).

<p>Конкурентный доступ, управляемый контейнером</p>

При таком доступе (он является подходом по умолчанию) контейнер отвечает за управление конкурентным доступом к экземпляру одиночного EJB-компонента. Тогда вы сможете использовать аннотацию @Lock для указания того, как контейнер должен управлять доступом при вызове метода клиентом. Эта аннотация может принимать значение READ (общая блокировка) или WRITE (эксклюзивная блокировка).

• @Lock(LockType.WRITE) — метод, ассоциированный с эксклюзивной блокировкой, не позволит выполнять конкурентные вызовы до тех пор, пока не завершится обработка, осуществляемая этим методом. Например, если клиент C1 вызовет метод с эксклюзивной блокировкой, то клиент C2 не сможет вызвать этот метод, пока клиент C1 не закончит.

• @Lock(LockType.READ) — метод, ассоциированный с общей блокировкой, позволит выполнять любое количество других конкурентных вызовов для экземпляра EJB-компонента. Например, два клиента — C1 и C2 — смогут одновременно получить доступ к методу с общей блокировкой.

Аннотацией @Lock можно снабдить классы, методы либо и те и другие сразу. Если снабдить ею класс, то это будет означать, что она распространяется на все методы. Если вы не укажете атрибут блокировки конкурентного доступа, то по умолчанию будет предполагаться @Lock(WRITE). В коде, приведенном в листинге 7.11, показан CacheEJB с блокировкой WRITE в классе EJB-компонента. Это подразумевает, что для всех методов будет иметь место конкурентный доступ WRITE за исключением getFromCache(), по отношению к которому осуществляется переопределение с использованием READ.

Листинг 7.11. Одиночный сессионный EJB-компонент с конкурентным доступом, управляемым контейнером

@Singleton

Перейти на страницу:

Похожие книги