Внедрение зависимостей с Spring (аннотации JSR 330) в WebSphere 7 не работает

У меня есть корпоративное приложение, построенное на Java 6, Spring Framework 3.1.2 и Mule-ESB 3.3.0, среди других библиотек, не связанных с этим вопросом.

Все наши компоненты и службы объявляются с @Named и @Inject JSR-330, соответственно, для автоматического сканирования компонентов и для внедрения зависимостей (без EJB, только для служебных компонентов). При развертывании в JBoss 4.2.3 (наша тестовая среда) все работает отлично. Однако при развертывании в WebSphere 7 аннотации JSR-330, похоже, не работают. @Named помеченные @Named вообще не обнаруживаются.

Я могу заверить, что все настроено правильно (так как он работает в JBoss). В частности, <context:component-scan/> правильно определил атрибут base-package и правильно настроил атрибут scope-resolver для использования Jsr330ScopeMetadataResolver (мы пробовали и без него).

Я знаю, что WebSphere 7 (7.0.0.23) может не поддерживать аннотации такого рода. Я еще не протестировал его с @Component и @Autowired Spring. К сожалению, мы бы очень хотели использовать аннотации JSR 330, чтобы наши классы не зависели напрямую от Spring, даже если мы используем Spring Framework под капотом.

Тем не менее, хотя я потратил один полный рабочий день на поиски определенного заявления о том, что WebSphere 7 не поддерживает аннотации JSR 330, я пока ничего не нашел.

Кроме того, я не понимаю, почему это не сработает, поскольку я предполагаю, что Spring Framework - это тот, кто выполняет всю работу через директиву <context:component-scan/> в файле application-context.xml.

Кто-нибудь может пролить свет на этот вопрос?

Есть ли способ активировать внедрение зависимостей через аннотации в WebSphere 7?

Если я переключусь обратно с аннотаций @Named/@Inject JSR 330 на собственные Spring @Component и @Autowired, это может сработать?

В отчаянной попытке я могу расширить Spring ComponentScanBeanDefinitionParser чтобы он обнаруживал аннотации JSR 330 даже в WebSphere 7?

Если ничего не работает, я в конечном итоге вернусь к простой конфигурации XML. Однако это крайне нежелательно, поскольку в XML будут вручную настроены сотни компонентов.

Ответы

Ответ 1

WebSphere 8 - это правильная версия для использования; он поддерживает EE6 (WebSphere 7 - EE5), который, в свою очередь, содержит CDI 1.0 (следовательно, JSR 299).

Ниже приведен фрагмент DeveloperWorks, в котором суммируется взаимосвязь между версиями WebSphere, JSR 299 и JSR 300

Инъекционная инъекция - это технология, которая много раз, прежде чем переходить в мир Java EE. Популярны библиотеки Spring и Google Guice Реализации. В JSR 330 была сделана попытка включить эти возможностей на платформе J2SE. JSR 299 - это спецификация, которая использовали API, определенные в JSR 330, и добавили дополнительные возможности для поддержка Java EE требует. IBM WebSphere Application Server V8 и V8.5 (профили без доступа) являются полностью совместимыми контейнерами Java EE 6 и реализовать JSR 299.

Ответ 2

В конце концов я придумал обходной путь, расширив функции Component Scan и Autowire Spring Framework.

Сначала я добавил фильтр включения в компонентный сканер, так что аннотации @Named также считались подходящими для обнаружения и регистрации в контейнере Spring:

<context:component-scan base-package="com.mycompany.mysystem">
    <context:include-filter type="annotation" expression="javax.inject.Named" />
</context:component-scan>

После этого я также добавил определение bean в org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcesso‌​r, расширив права на автоуниверсирование до аннотаций @Inject:

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
    <property name="autowiredAnnotationType" value="javax.inject.Inject" />
</bean>

Изначально это работало отлично, чтобы "реактивировать" аннотации @Named и @Inject. Тем не менее, у меня все еще были проблемы с конфликтом beans в процессе разрешения кандидатов на автоувеличивание. Это было связано с различиями в процессе разрешения по умолчанию Spring и JSR-330. Это не было большой проблемой, так как только несколько beans попали в этот сценарий. Все они были решены путем добавления некоторых стратегически размещенных аннотаций @Qualifier.

Теперь все работает отлично и элегантно, с несколькими дополнительными конфигурациями. Тем не менее, я до сих пор не понимаю, почему это произошло. Все, что я знаю, это то, что следующие три строки появляются, когда я развертываю приложение в JBoss 4.2.3. С другой стороны, они не отображаются в WebSphere:

INFO  [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] JSR-330 'javax.inject.Named' annotation found and supported for component scanning

и

DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] Creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
INFO  [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] JSR-330 'javax.inject.Inject' annotation found and supported for autowiring

Я до сих пор не знаю, почему это происходит, поскольку, как сказал @Dreamer, это должна быть ответственность Spring и, следовательно, из бизнеса WebSphere.

Если у кого-то есть такая подсказка, пожалуйста, просветите нас. Я уверен, что было бы прекрасно разъяснить всем, кто участвует в этом обсуждении.

Ответ 3

Согласитесь с duffymo, он должен работать на WS 7. Поскольку Spring находится поверх Websphere, поэтому аннотация Spring отсутствует в бизнесе webshere (вроде).

Одна вещь, которую вам, вероятно, нужно проверить на WS 7 (даже если вы сказали, что каждая конфигурация правильная, так как она работает на JBoss), щелкните ваше приложение → нажмите Class loading and update detection, убедитесь, что отмечен Classes loaded with local class loader first (parent last). Это заставило бы сервер брать вашу библиотеку приложений, а затем библиотеку websphere.