Ваш анализ кажется обоснованным, и вы правы, когда говорите, что не можете динамически развернуть MDB для соответствия JCA.
Еще несколько дизайнерских идей:
Вы могли бы написать JCA-соединитель, который возвращает SocketConnections
(в духе JMS), который вы могли бы использовать для чтения из сокета. Чтобы продолжить аналогию с JMS, MDB представляет MessageListener
, а то, что вы бы выставили, - MessageConsumer
.
Вы можете использовать периодический таймер для имитации потока. Вместо потока с циклом while у вас есть таймер, который перепланировал себя. Я использовал это для одного приложения, чтобы иметь фоновый процесс, и это работало нормально. Обратите внимание, что я также порождал потоки прямо из EJB-компонентов для выполнения некоторых параллельных вычислений в другом приложении, и это тоже хорошо работало. Но потоки с коротким сроком действия и бизнес-метод в компоненте будут ждать, пока все не будет завершено, так что это не является серьезным нарушением спецификации.
Еще один дизайн - соединитель JCA обрабатывает потоки и т. Д. И доставляет все сообщения в MDB. MDB будет принимать данные вместе с информацией о «канале», которому соответствуют данные, например, Разъем порта. Это как мультиплексирование всего в одном MDB, которое затем демультиплексирует данные. Ваш коннектор может предоставить дополнительный API для управления созданием потоков и т. Д., И этот интерфейс может быть внедрен в ваш EJB (аналогично ConnectionFactory
). Ваш коннектор может предоставить дополнительный API для управления созданием потоков и т. Д. Не совсем понятно, но я надеюсь, что вы поняли идею. Если я прав, соединитель JCA может обеспечить синхронную доставку данных в MDB, по крайней мере, для каждого сокета, чтобы MDB обрабатывал данные в правильном порядке.
Я бы пошел на # 3, , если позволяет время разработки .
EDIT
Этот выбор действительно частично является вопросом чистоты дизайна. Одна проблема с порожденными пользователями потоками состоит в том, что вы, очевидно, не можете использовать для них декларативные транзакции. Вы можете использовать UserTransaction
для разграничения транзакций самостоятельно. Я не знаю, насколько хорошо вы можете использовать EntityManager
также в такой теме. Если вы в основном обрабатываете данные и не используете много функций промежуточного программного обеспечения, вы можете порождать потоки самостоятельно. Смотрите другой мой ответ: Как EJB может распараллелить длинный процесс, интенсивно использующий процессор? . Другие вещи, которые приходят мне в голову (не знаю, проблематичны они или нет): менеджер безопасности может препятствовать созданию потока (?), А не создавать их, так как deamon threads может помешать приложению. сервер правильно выключен (?). Обратите внимание, что я порождаю темы из ServeletContextListener
при запуске, и это работало просто замечательно. Этот прием часто используется, даже если он нарушает спецификацию. То же самое может стать правдой для "недавно" введенных синглтон-бинов. Так что, если у вас мало времени, вы, конечно, можете попробовать свое предложение с помощью одноэлементного компонента и посмотреть, что работает / не работает.