Spring: Доступ к правильному WebApplicationContext с объявлением нескольких диспетчеров - PullRequest
3 голосов
/ 07 октября 2010

В моем приложении объявлено два контекста Spring - один для запросов Spring-MVC, а другой для запросов Flex / BlazeDS MessageBroker, сопоставленных с различными шаблонами URL:

<servlet-mapping>
    <servlet-name>spring-mvc</servlet-name>
    <url-pattern>/app/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>flex</servlet-name>
    <url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>

Существует общая конфигурация контекстаобъявлено, (/WEB-INF/applicationContext.xml), а затем каждый из двух контекстов имеет свои собственные конфигурации, объявленные в spring-mvc-servlet.xml и flex-servlet.xml соответственно.

Внутри flex-servlet.xml У меня есть объявленные bean-компоненты, специфичные для контекста flex,Однако, когда поступает вызов http://localhost/messagebroker/*, я получаю сообщения об ошибках, которые недоступны для этих bean-компонентов.

Код, о котором идет речь, находится внутри пользовательского компонента Spring, поэтому непосредственно ссылается на WebApplicationContext по порядкучтобы получить доступ к объявленным bean-компонентам:

public ISerializer getSerializer(Object source,boolean useAggressiveSerialization)
{
    ServletContext ctx = FlexContext.getServletContext();
    WebApplicationContext springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(ctx);
    String serializerBeanName = springContext.getBeanNamesForType(ISerializer.class);
}

Этот подход работает, когда я работаю с одним контекстом.Однако он также должен поддерживать, когда выполняется несколько контекстов.

Устанавливая точку останова, я вижу, что значение springContext является корневым контекстом с единственным configLocation - /WEB-INF/applicationContext.xml

Я предполагаю, что это проблема - так как ISerializer, требуемый вышеупомянутым кодом, объявлен в flex-servlet.xml.

Как мне изменить вышеуказанный код для поддержки обоих сценариев?(Один контекст и несколько контекстов)?

РЕДАКТИРОВАТЬ: Приведенный выше код находится внутри ManageableComponentFactoryBean , который работает как фабрика пользовательских компонентов.Кажется, что интерфейс ApplicationContextAware не учитывается в сгенерированных классах.Например:

<bean id="dpHibernateRemotingAdapterComponentFactory"
    class="org.springframework.flex.core.ManageableComponentFactoryBean">
    <constructor-arg
        value="org.dphibernate.adapters.RemotingAdapter" />
    <property name="properties">
        <value>
            {"dpHibernate" :
                {
                    "serializerFactory" : "org.dphibernate.serialization.SpringContextSerializerFactory"
                }
            }
        </value>
    </property>
</bean>

Код, указанный выше, находится внутри org.dphibernate.serialization.SpringContextSerializerFactory.Создание этого SpringContextSerializerFactory орудия ApplicationContextAware не оказывает никакого влияния.

Ответы [ 3 ]

3 голосов
/ 07 октября 2010

Если flex является DispatcherServlet, и по какой-то причине вы не можете следовать предложению Томаса Нарроса, вы можете получить контекст, связанный с текущим DispatcherServlet, используя RequestContextUtils.getWebApplicationContext(request).

Существует также удобный метод RequestContextUtils.getWebApplicationContext(request, ctx), который возвращает корневой контекст, если DispatcherServlet не доступен.

2 голосов
/ 07 октября 2010

Объявите свой пользовательский компонент как поддерживающий Spring Context:

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public MyCustomBean  implements ApplicationContextAware {

  private ApplicationContext springContext;

  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    springContext = applicationContext;
  }

  public ISerializer getSerializer(Object source,boolean useAggressiveSerialization)
{
    String serializerBeanName = springContext.getBeanNamesForType(ISerializer.class);
  }
}

При инициализации компонента Spring получает доступ к методу setApplicationContext вашего компонента, передавая в качестве аргумента контекст, в котором он создается. Там вы можете использовать его в любое время.

0 голосов
/ 07 октября 2010

Хмммм ..... У меня есть почти такая же декларация в моем приложении Spring / Flex, использующая интеграцию Spring / Flex, и существует только один контекст приложения. Может ли это быть проблема? У вас есть компоненты, объявленные в файле контекста Flex, которых нет в файле контекста MVC, и они на самом деле не загружаются?

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