Добавьте бобы весны в EJB3 - PullRequest
9 голосов
/ 09 марта 2011

Я пытаюсь внедрить бины Spring в EJB, используя @Interceptors(SpringBeanAutowiringInterceptor.class), но я не могу заставить его работать с beanRefContext.xml примерами, которые я видел.

Вот мой EJB:

@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class AlertNotificationMethodServiceImpl implements
        AlertNotificationMethodService {

    @Autowired
    private SomeBean bean;
}

Я предоставил beanRefContext.xml следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="...">

   <!-- Have also tried with ClassPathXmlApplicationContext -->
   <bean id="context"
        class="org.springframework.web.context.support.XmlWebApplicationContext">
        <property name="configLocations" value="/config/app-config.xml" />
   </bean>

</beans>

Но, похоже, он воссоздает компоненты вместо получения существующего ApplicationContext.Я получаю следующее исключение, потому что один из моих компонентов - ServletContextAware.

java.lang.IllegalArgumentException: Cannot resolve ServletContextResource
without ServletContext

При использовании SpringBeanAutowiringInterceptor не должен ли он получить ApplicationContext вместо создания нового?

Я также попытался изменить свой файл web.xml, чтобы contextConfigLocation указывал на beanRefContext.xml, надеясь, что он загрузит мою конфигурацию Spring, но я получаю то же исключение, что и выше.это правильно?Примеры, которые я видел, похоже, используют тот же метод, который я использую, и я предполагаю, что бины воссоздаются при вызове Interceptor (или это то, как он должен работать, и я неправильно понял).

1 Ответ

11 голосов
/ 10 марта 2011

При использовании SpringBeanAutowiringInterceptor не должен ли он получить ApplicationContext вместо создания нового?

Да, и это фактически то, что он делает.Он использует механизм ContextSingletonBeanFactoryLocator, который, в свою очередь, управляет несколькими экземплярами ApplicationContext как статическими одиночками (да, даже Spring иногда вынужден прибегать к статическим одиночкам).Эти контексты определены в beanRefContext.xml.

Ваша путаница, похоже, связана с ожиданием того, что эти контексты имеют какое-либо отношение к ApplicationContext вашего веб-приложения - они не имеют, они полностью отделены.Таким образом, ContextLoader вашего веб-приложения создает и управляет контекстом на основе определений bean-компонентов в app-config.xml, а ContextSingletonBeanFactoryLocator создает другой.Они не будут общаться, если вы не скажете им.EJB не могут овладеть контекстом веб-приложения, так как EJB находятся вне этой области.

Что вам нужно сделать, это переместить компоненты, которые должны использоваться вашими EJB, из app-config.xml в другоефайл определения бина.Этот извлеченный набор определений bean-компонентов сформирует основу для нового ApplicationContext, к которому (a) будут обращаться EJB-компоненты, и (b) будет действовать как родительский контекст контекста вашего веб-приложения.

В порядкечтобы активировать родительско-дочернюю ссылку между контекстом вашего веб-приложения и новым контекстом, вам нужно добавить дополнительный <context-param> к вашему web.xml, называемому parentContextKey.Значением этого параметра должно быть имя контекста, определенного в beanRefContext.xml (т.е. context, в вашем примере).

Бины, которые остаются в контексте веб-приложения, смогут ссылаться на биныв родительском контексте, как и EJB.Однако EJB-компоненты не смогут ссылаться на что-либо в контексте веб-приложения.

Кроме того, вы не можете использовать XmlWebApplicationContext в beanRefContext.xml, поскольку этот класс требует осведомленности о веб-приложении, а ContextSingletonBeanFactoryLocator не может предоставитьэто осознание.Вы должны придерживаться ClassPathXmlApplicationContext там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...