如何从 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?的主要内容,如果未能解决你的问题,请参考以下文章

如何确保从上下文而不是缓存中获取 Core Data Fetched Property?

根上下文和调度程序 servlet 上下文到底是如何进入 Spring MVC Web 应用程序的?

不理解 Java EE 中上下文的概念

无法过滤上下文根 Servlet 请求

React Context API,从子组件设置上下文状态,而不是将函数作为道具传递

如何将 fetch() 函数的结果传递给 React 上下文值,而不是我为钩子设置的默认值?