有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring:在声明多个Dispatcher的情况下访问正确的WebApplicationContext

我在应用程序中声明了两个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.xmlflex-servlet.xml中声明了自己的配置

flex-servlet.xml中,我声明了特定于flex上下文的bean。然而,当调用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内部,它看起来像一个自定义bean工厂。似乎生成的类不支持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) 个答案

  1. # 1 楼答案

    将自定义组件声明为Spring上下文感知:

    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);
      }
    }
    

    在bean初始化时,Spring将访问bean的setApplicationContext方法,并将创建它的上下文作为参数传递。在那里,你可以随时使用它

  2. # 2 楼答案

    如果flex是一个DispatcherServlet,并且由于某种原因您无法遵循Tomás Narros的建议,那么您可以使用RequestContextUtils.getWebApplicationContext(request)获得与当前DispatcherServlet相关的上下文

    还有一个方便的方法RequestContextUtils.getWebApplicationContext(request, ctx),如果DispatcherServlet的方法不可用,它将返回根上下文

  3. # 3 楼答案

    嗯。。。。。在我的Spring/Flex应用程序中,使用Spring/Flex集成时,我有几乎完全相同的声明,并且只有一个应用程序上下文。这就是问题所在吗?你在Flex上下文文件中声明了不在MVC上下文文件中的bean,但它们没有真正被加载