【问题标题】:How to get beans defined in main-servlet.xml from controller如何从控制器获取 main-servlet.xml 中定义的 bean
【发布时间】:2014-11-27 15:36:48
【问题描述】:

我知道我的 main-servlet.xml 中的 bean 在子上下文中。根据研究,我知道我可以通过 WebApplicationContextUtils 在 GreetingController 中获取根 ApplicationContext。我会得到 null 因为我没有在 web.xml 中定义这样的根上下文。

现在我的问题是如何在没有 @AutoWired 注释的情况下获取子上下文并执行类似 childContext.getBean("forfun") 的操作,我想我已经对其进行了测试并且它可以工作;

提前感谢您的阅读和信息。

编辑:自动连接 ApplicationContext 或实现 ApplicationContextAware 将帮助您获取子应用程序上下文和根应用程序上下文。

Edit2:我找到了另一种获取defaultdispacher创建的上下文的方法,该上下文实际上存储在名为org.springframework.web.servlet.FrameworkServlet.CONTEXT.(servletName)的servletcontext属性中 假设您的默认 servlet 是 main,您可以使用以下代码通过 defaultdispacher[main-servlet.xml] 获取上下文 craete。

ApplicationContext context1=(WebApplicationContext) request.getSession().getServletContext().getAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.main")

但还是不明白为什么在 WebApplicationContextUtils 方法中我们不能访问子上下文。

web.xml 文件

<webapp>
<servlet>
<servlet-name>main</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/main-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/main/*</url-pattern>
</servlet-mapping>
</web-app>

main-servlet.xml

<beans>
<bean name ="/testing/*" class="springmvc.GreetingController"></bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/Jsp/"
p:suffix=".jsp"/>
<bean id="forfun" class="springmvc.Foo"></bean>
</beans>

GreetingController.java

@Controller
public class GreetingController {

@AutoWired
Foo forfun;//this works even if forfun is defined in main-servlet.xml

@RequestMapping("/testing")
public String testing(HttpServletRequest request){
    ApplicationContext context = 
                WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
        Foo f=(Foo) context.getBean("forfun");//supposed to work if i have it defined in root context
    /*
    I would something like this
    ChildContext child = Utils.getChildContext(request);
    Foo f=(Foo) child.getBean("forfun");
    */
        return "test";
    }
}

【问题讨论】:

  • 为什么要通过WebApplicationContext获得它?
  • 不是出于实际原因,只是尝试看看有没有办法。

标签: java spring spring-mvc servlets model-view-controller


【解决方案1】:

您在上面声明的main-servlet.xml 由您的DispatcherServlet 加载。

可以用

注入对应的WebApplicationContext
@Autowired
private WebApplicationContext context;

并使用它来获取在该上下文或父级中定义的任何 bean。

请注意,只有当您将其注入的 bean 是在由 DispatcherServlet 创建的 WebApplicationContext 中创建时,这才有效。

或者,如 M. Deinum 在 cmets 中所述,有一个名为 RequestContextUtilsstatic 实用程序类,它提供了一个 getWebApplicationContext(ServletRequest) 方法来做同样的事情。

【讨论】:

  • 非常感谢您的回复,所以这个自动装配的 WebApplicationContext 应该包含从父上下文到子上下文的所有 bean?
  • @Jing 注入的WebApplicationContext 是包含它被注入 的bean 的那个。如果那是由DispatcherServlet(子)加载的那个,则只有如果存在,您将可以访问由ContextLoaderListener(父)加载的WebApplicationContext
  • 作品~。只是出于好奇,有没有其他方法可以在没有注释的情况下获取上下文?以及为什么 WebApplicationContextUtils.getRequiredWebApplicationContext() 没有得到“子上下文”?
  • @Jing getRequiredWebApplicationContext 返回由ContextLoaderListener 加载的WebApplicationContext(如果不存在则抛出异常)。没有其他标准方法可以让DispatcherServlet 加载。
  • 真的非常感谢。刚刚找到了有线的方式来获取它,我确定它不是标准的,不推荐。只是为了好奇。 :D
猜你喜欢
  • 1970-01-01
  • 2011-08-31
  • 1970-01-01
  • 2015-06-11
  • 2012-11-20
  • 2023-03-19
  • 2016-04-19
  • 2018-02-17
  • 1970-01-01
相关资源
最近更新 更多