如何从 servlet 上下文而不是根上下文中获取 bean?

Posted

技术标签:

【中文标题】如何从 servlet 上下文而不是根上下文中获取 bean?【英文标题】:How can I get a bean from the servlet context instead of the root context? 【发布时间】:2013-05-21 07:36:32 【问题描述】:

我有一个 spring-mvc 应用程序,它在 DispatcherServlet 上下文配置中使用 <context:component-scan base-package="com.example.app" /> 自动装配 bean。

我现在有一种情况,我希望从非 bean 类访问服务 bean,特别是 RequestContextAwareTag 实现。

我可以访问在根上下文中注册的bean,如下所示:

ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(
      pageContext.getSession().getServletContext());
MyService svc = ctx.getBean(MyService.class);

如果 bean 在调度程序上下文中注册,我会得到一个 NoSuchBeanDefinitionException

如果可能的话,我实际上更希望我的 @Service bean 在根上下文中注册,而不拾取 @Controller bean,然后在调度程序上下文中拾取 @Controller bean。 <context:component-scan/> 的问题在于它同时兼顾了两者。

如果这不可能,我需要一种方法来访问调度程序 ApplicationContext 以检索服务 bean。

非常感谢任何指导。

【问题讨论】:

您是否尝试过在您的 bean 配置文件中实现 ApplicationContextAware 并实例化该类? 不幸的是,对于标签来说这是不可能的,因为它们是在使用标签的每个页面请求上创建的。 【参考方案1】:

我已经设法通过使用exclude-filterinclude-filter 拆分两个component-scan 配置来解决这个问题。

根上下文:

<context:component-scan  base-package="com.example.app">
  <context:exclude-filter
    expression="org.springframework.stereotype.Controller"
    type="annotation"/>
</context:component-scan>

servlet 上下文:

<mvc:annotation-driven/>
<context:component-scan  base-package="com.example.app">
  <context:include-filter
    expression="org.springframework.stereotype.Controller"
    type="annotation"/>
</context:component-scan>

【讨论】:

root-context 表示在 web-xml 中用标签“context-param”指出一个声明的bean?

以上是关于如何从 servlet 上下文而不是根上下文中获取 bean?的主要内容,如果未能解决你的问题,请参考以下文章