没有Spring MVC的Spring Web上下文

时间:2014-09-07 08:40:17

标签: java spring spring-mvc

我想使用Spring在Web应用程序中管理我的JPA DAO,并尝试按照Spring网站示例来了解如何执行此操作。

我正在考虑使用AnnotationConfigWebApplicationContext代替AnnotationConfigApplicationContext来引导Spring。

在示例中,它与org.springframework.web.servlet.DispatcherServlet一起使用,但我想在没有Spring MVC的情况下使用它。

我的web.xml看起来如下:

    ...
<web-app>
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext 
        </param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.foo.Application</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
...
</web-app>

我的配置类如下所示:

...
@Configuration
@ComponentScan(basePackages={"com.foo.service"})
public class Application {

    @Bean
    MessageService mockMessageService() {
        return new MessageService() {

            @Override
            public String getMessages() {
                return "Hello Spring World!";
            }
        };
    }

}

是否可以将此示例中的mockMessageService注入到我的servlet中,还是必须为我的Web应用程序创建一个单独的中央集线器,其中服务是由servlet调用的?

问题是如果我在包com.foo.service中有我的servlet并尝试使用

@Autowired

获得依赖或尝试一些类似的方法服务不会被注入,我不知道问题出在哪里。有可能这样做吗?或者我应该为AnnotationConfigWebApplicationContext添加一些工作吗?

2 个答案:

答案 0 :(得分:2)

Servlet由servlet容器管理,而不是由spring管理。 Spring不会注入servlet,因为它不会实例化它们。

如果你想在servlet中访问由spring管理的bean,你必须像spring DispatcherServlet那样进行访问。

E.g。从WebApplicationContext

获取ServletContext
 javax.servlet.ServletContext servletContext = ...;
 WebApplicationContextUtils.getWebApplicationContext(servletContext);

这是有效的,因为ContextLoaderListener可确保WebApplicationContext可用作ServletContext属性。

由于WebApplicationContextApplicationContext,您可以自动装配已在弹簧容器外实例化的bean。

例如

ApplicationContext appContext = ...;
AutowireCapableBeanFactory acbf = context.getAutowireCapableBeanFactory();

SomeBean someBean = new SomeBean();
acbf.autowireBean(someBean);

只需将@Autowired注释放在SomeBean

的字段上即可

更简单的方法是扩展spring org.springframework.web.servlet.FrameworkServlet并实现doService方法。有关详细信息,请阅读FrameworkServket的javadoc。

答案 1 :(得分:2)

如果你有一个servlet,你可以使用类似下面的东西在init方法上连接它:

public class MyServlet implements javax.servlet.Servlet {

  @Autowired
  MyBean myBean;

  @Override
  public void init(ServletConfig arg0) throws ServletException {
    final AutowireCapableBeanFactory autowireCapableBeanFactory=WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory();
    autowireCapableBeanFactory.autowireBean(this);
  }
 //....
}

如果我有很多servlet,将init方法提取到某个可重用的父类中是很方便的,例如

public class AutowiredServlet implements javax.servlet.Servlet {

  @Override
  public void init(ServletConfig arg0) throws ServletException {
    final AutowireCapableBeanFactory autowireCapableBeanFactory=WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory();
    autowireCapableBeanFactory.autowireBean(this);
  }
}

并为每个需要自动装配的servlet扩展该类。