Инъекция зависимостей EJB 3 - слишком много вариантов?

Мы начинаем новый проект на основе EJB 3.0. У меня есть фон "spring" (и люблю его), поэтому для меня важна свободная связь и тестируемость. Этот пост не должен быть о "ejb vs. spring". Было бы прекрасно, если бы у вас уже был настоящий опыт проекта с этим.

вот пример кода для демонстрации проблемы:

client → ejb → соавтор 1 → соавтор.. → соавтор n

<!-- language: java -->
@Stateless
public class SampleService {

    // or @Inject via CDI
    // or @Autowired via Spring
    @EJB // or just use a stateless session bean via EJB 3.0
    private Bank bank;

    // same for this component
    @EJB
    private Calculator calc;

    // both collaborators must be settable from outside, to make everything testable (and mockable)

    /**
     * sample "business service" called from client
     */
    public void debit(BigDecimal amount){
        calc.calculate(amount.subtract(new BigDecimal(100)));
        bank.debit(amount);
    }

}

// or via @Component (Spring), or CDI?
@Stateless // or Stateless Session bean with optional @Service/@Singleton annotation?
public class Calculator {
    public void calculate(BigDecimal subtract) {
        // calculate stuff....
    }
}

// or via @Component (Spring), or CDI?
@Stateless // or Stateless Session bean with optional @Service/@Singleton annotation?
public class Bank {
    public void debit(BigDecimal amount) {
        // ...
    }
}

Я хочу знать, что является наилучшим способом реализации инъекции зависимостей для всех сотрудников и их сотрудников в ejb 3.0? Коллабораторы в этом смысле могут быть очень маленькими выделенными классами.

мы обсуждали следующие варианты до сих пор и, как всегда, еще не имеем правильного вывода:)

  • используйте только стандарт ejb со всем, что связано с сеансом без состояния bean и всеми последствиями (например, пулом, обработкой ресурсов и т.д.).

  • использовать сессию без состояния beans как "бизнес-компоненты" (точки входа) и оттуда

a) spring проводные зависимости (через интеграцию "jboss snowdrop" )

b) Связанные с CDI зависимости (через WELD для ejb 3.0 и jboss eap 5.1)

Мне не нужно знать, как я могу использовать beans в unit test. ответом, которым я являюсь, является наилучшим подходом для подключения всех зависимостей внутри запущенного сервера приложений (spring против guice против CDI против EJB). Мне нужно только знать график из внешнего EJB ( "точка входа в бизнес" ) вниз. так что все снаружи (сервлеты, интерфейс и т.д.) не является предметом этого вопроса:)

пожалуйста, предположим, что для проекта установлены EJB 3.0 и jboss eap 5.1:)

с нетерпением жду ваших ответов и, надеюсь, некоторые знания, основанные на проектах.

Ответ 1

Ну, в общем, на Java есть "слишком много вариантов", поэтому, конечно, и в этой области. Я бы не стал описывать EJB как общую концепцию Injection Dependency Injection, вместо этого они используют DI для своих целей. Если это то, как вы хотите кодировать, вы должны посмотреть, как добавить структуру для этой цели. Если вы знаете и как Spring, пойдите для этого. Я использовал Guice с EJB (здесь - хорошая поваренная книга), чтобы хорошо повлиять, если вам нужна еще одна основа, чтобы понять, как это сделать это.

Ответ 2

Если вам требуется управление транзакциями уровня метода, безопасность, управление concurrency или любые другие сервисы, которые может предложить сеанс bean, затем сделать их сеансом EJB beans. Вы можете начать с управляемых beans, а затем сделать их сеансом beans как и когда вам нужно.

Если вы хотите вставить этот сеанс beans в управляемый beans (который в CDI есть что-нибудь в файле jar, содержащем файл beans.xml в каталоге meta-inf), используйте @EJB. Если вы хотите ввести простой управляемый bean в сеанс bean, используйте @Inject.

Если вы хотите ввести удаленный сеанс beans (или любой удаленный ресурс Java EE), эта ссылка объясняет, как вы можете сделать это через класс адаптера. По сути, он держит все ваши неприятные строки для поиска и т.д. В одном месте и позволяет вам обрабатывать эти удаленные ресурсы так же, как и любые другие инъекционные bean (через аннотацию @Produces на переменные-члены адаптера). Вам не обязательно это делать, но рекомендуется.

Включение приложений класса safe

Ответ 3

Я бы определенно проголосовал против микширования фреймворков.

Я работаю над проектом, который подключен к EJB, Spring и JBoss Seam (а также имеет половину Flex, полу-JSF-интерфейс). Настоящий технологический зоопарк!
Во всяком случае, подключение всего этого не самое худшее, эти рамки имеют гибкие возможности впрыска. Тестирование также более или менее терпимо. Наиболее болезненным было избавиться от утечек памяти, вызванных различными моделями lifecylce, синхронизировать транзакцию и очистить поведение потоков.

Теперь мы переходим к чистой Java EE 6 (избавляемся от Spring, Flex и переходим от Seam к CDI). До сих пор мы очень довольны результатами. Кстати, я не критикую Spring. Придерживайтесь с помощью Java EE или Spring стека, смешивая их, просто спрашивайте о проблемах.

Ответ 4

Если ваша основная цель - разрешить инъекцию зависимостей для тестирования, я бы порекомендовал просто дать возможность устанавливать эти значения, изменив их на защищенные или предоставив им сеттеры. Я поклонник использования Mockito для того, чтобы заглушить все в Java EE EJB 3.0 и при любом тестировании вне интеграционного тестирования, чтобы просто разрешить Mockito блокировать методы для меня, но если вы ищете полную инъекцию зависимостей, как возможность иметь несколько разных beans, основанных на одном классе, но с разными зависимостями, которые я бы рекомендовал, поскольку Yishai сказал и пошел с Spring сверху.