Внедрение зависимостей с 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.AutowiredAnnotationBeanPostProcessor
, расширив права на автоуниверсирование до аннотаций @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.