【问题标题】:injecting directly to servlet instead of new ClassPathXmlApplicationContext直接注入到 servlet 而不是 new ClassPathXmlApplicationContext
【发布时间】:2013-07-10 13:41:34
【问题描述】:

我有一个包含许多 servlet 的大型 Java 项目。并且每个 servlet 需要 使用以下命令从同一个 bean 文件中获取对象:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

然后我用

     context.getBean("<BEAN_NAME">);

其中一些甚至需要获取相同的对象。

问题是是否可以将我想要的对象直接注入 servlet 而无需手动读取 bean 文件。

每个 servlet 都在 web.xml 中配置。

任何有关该问题的信息将不胜感激!

谢谢

【问题讨论】:

    标签: java applicationcontext spring-bean


    【解决方案1】:

    您是否考虑过让您的 servlet 实现 HttpRequestHandler

    然后您必须将您的 Servlet 声明为命名为 Spring bean 并在 web.xml 上使用相同的名称,然后您可以简单地使用 @Autowired 注释将您的 Spring bean 注入您的 Servlet

    更多信息http://www.codeproject.com/Tips/251636/How-to-inject-Spring-beans-into-Servlets

    示例代码:

    
      @Component("myServlet") 
       public class MyServlet implements HttpRequestHandler {
    
            @Autowired
            private MyService myService;
    ...
    

    示例 web.xml

    <servlet>     
                <display-name>MyServlet</display-name>
                <servlet-name>myServlet</servlet-name>
                <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet
               </servlet-class>
        </servlet>
        <servlet-mapping>
                <servlet-name>myServlet</servlet-name>
                <url-pattern>/myurl</url-pattern>
        </servlet-mapping>
    

    【讨论】:

    • 你不会直接使用DispatcherServlet 和完整的 Spring MVC 套件吗?
    • 是的,我在发布问题之前先用谷歌搜索过。在理解 AutoWired 功能时遇到问题。我习惯于使用 xml 配置进行注入。没有代码注释。
    【解决方案2】:

    由于您有一个 Web 应用程序,我会使用包含在 spring-web 中的 WebApplicationContext,它在您的 Web 应用程序部署时加载并在取消部署时正确关闭。您所要做的就是在您的web.xml 中声明ContextLoaderListener

    <listener>
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/applicationContext*.xml</param-value>
    </context-param>
    

    然后您可以从任何 servlet 访问您的 ApplicationContext

    ApplicationContext ctx = WebApplicationContextUtils
        .getRequiredWebApplicationContext(getServletContext());
    MyBean myBean = (MyBean) ctx.getBean("myBean");
    myBean.doSomething();
    

    优点是,您的上下文在所有 servlet 之间共享。

    参考资料:

    【讨论】:

    • 我不明白什么是 MyBeans 类。在我只使用 ApplicationContext 来获取 bean 之前。现在我需要为它创建一个类吗?
    • 或者我可能遗漏了什么.. ctx.getBean 获取 bean 本身而不是 bean.xml 文件?
    • ahah ok.. 那么我如何准确地告诉它要转到哪个 bean 文件?
    • @ufk:我编辑了答案以包含 Spring 文档中的该部分。通过 contextConfigLocation context-param 指定 XML/XML 的位置。
    • 哦,没有我想象的那么复杂。
    【解决方案3】:

    您可以将SerlvetContextListenerServlet#init() 方法一起使用。当您的 servlet 容器创建 servlet 上下文时,它将在任何 ServletContextListeners 上调用 contextInitialized(),您可以在其中初始化应用程序单例/beans/等。

    public class YourServletContextListener implements ServletContextListener {
    
        @Override
        public void contextDestroyed(ServletContextEvent event) {
            // clear context
        }
    
        @Override
        public void contextInitialized(ServletContextEvent event) {
            // initialize spring context    
            event.getServletContext().setAttribute("context", springContext);
        }
    }
    

    此上下文(servlet 上下文)中的所有 Servlet 都可以访问这些属性。

    在Servletinit()方法中,你只需要获取属性

    public class YourServlet implements Servlet {
    
        @Override
        public void init(ServletConfig config) {
            config.getServletContext().getAttribute("context");
            // cast it (the method returns Object) and use it
        }
    
        // more
    }
    

    【讨论】:

    • 用@nif 和你的回答我可以想出某种解决方案。现在检查它。谢谢
    猜你喜欢
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 2013-09-15
    • 1970-01-01
    • 2019-09-21
    • 2011-01-30
    • 2021-04-22
    相关资源
    最近更新 更多