【问题标题】:Spring configuration for webapps without spring MVC没有 spring MVC 的 webapps 的 Spring 配置
【发布时间】:2017-01-26 10:03:03
【问题描述】:

我正在尝试将我的多模块项目配置为在没有 Spring MVC 的情况下使用 Spring。

这是项目层次结构:

brewspberry-rpm-parent

---- brewspberry-api(包含网络服务)

---- brewspberry-core(包含服务和 DAO)

---- brewspberry-webapp(包含网页,servlet,...)

brewspberry-core 是 webapp 的 maven 依赖项。

我尝试做的是能够在 webapp 中自动装配核心 bean。我使用基于 Java 的配置。

这是我的 Spring webapp 初始化器:

public class SpringWebappInitializer extends
    AbstractAnnotationConfigDispatcherServletInitializer implements
    WebApplicationInitializer {

public void onStartup(ServletContext servletContext)
        throws ServletException {

    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

    rootContext.setServletContext(servletContext);

    // rootContext.setConfigLocation("net.brewspberry.util");

    rootContext.register(SpringCoreConfiguration.class);

    //servletContext.addListener(new ContextLoaderListener(rootContext));

    getWebAppContext(servletContext);

}




private void getWebAppContext(ServletContext servletContext) {
    // now the config for the Dispatcher servlet
    AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
    // mvcContext.setConfigLocation("net.brewspberry.util.config");
        mvcContext.register(SpringWebappConfiguration.class);


    ServletRegistration.Dynamic dispatcher = servletContext.addServlet(
            "DispatcherServlet", new DispatcherServlet(mvcContext));

    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("*.do");
}




@Override
protected Filter[] getServletFilters() {
    return null; // new Filter[] { new AuthentificationFilter() };

}

@Override
protected Class<?>[] getRootConfigClasses() {
    // TODO Auto-generated method stub
    return null;
}

@Override
protected Class<?>[] getServletConfigClasses() {
    // TODO Auto-generated method stub
    return null;
}

@Override
protected String[] getServletMappings() {
    // TODO Auto-generated method stub
    return null;
}
}

配置类是:

@Configuration
@EnableWebMvc
@ComponentScan({ "net.brewspberry" })
public class SpringWebappConfiguration extends WebMvcConfigurerAdapter {

@Override
public void configureDefaultServletHandling(
        DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("forward:/login.jsp");
}

@Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver.setPrefix("/");
    viewResolver.setSuffix(".jsp");
    return viewResolver;
}
}

我希望 servlet 可以从 Brewspberry-core 模块注入服务。

我尝试了 SO 上一篇文章中的解决方案,其中包括创建一个包含以下内容的抽象 Servlet:

@Override
public void init(ServletConfig arg0) throws ServletException {

    // Autowire beans in webapp

    final AutowireCapableBeanFactory autowireCapableBeanFactory = WebApplicationContextUtils
            .getWebApplicationContext(servletContext)
            .getAutowireCapableBeanFactory();
    autowireCapableBeanFactory.autowireBean(this);
}

我尝试了几件事,但在获取 servletContext 时仍然得到 NullPointerException :

  • 来自 arg0.getServletContext()

  • 通过自动装配

我确定核心配置在测试中有效。我遇到的问题是 webapp 到核心配置

更新

通过删除覆盖的 onStartup 方法并将两个配置类添加到 getRootConfigClasses(),创建了 servletContext:

@Override
protected Class<?>[] getRootConfigClasses() {

    return new Class<?>[]{SpringCoreConfiguration.class, SpringWebappConfiguration.class};
}

【问题讨论】:

  • 您正在扩展AbstractAnnotationConfigDispatcherServletInitializer,但正在努力不使用它应该使用的方式。以适当的方式使用它。此外,您尝试的内容仅适用于根上下文,ContextLoaderListener 加载的上下文不适用于另一个 servlet 加载的 ocntext。由DispatcherServlet 加载的ApplicationContext 默认为DIspatcherServlet 私有。

标签: spring spring-mvc servlets configuration


【解决方案1】:

您正在扩展AbstractAnnotationConfigDispatcherServletInitializer,但正在努力不使用它应该使用的方式。

用以下替换你的类

public class SpringWebappInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {SpringCoreConfiguration.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {        
        return new Class[] {SpringWebappConfiguration.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {"*.do"};
    }
}

这将注册所有需要的内容(包括正确的 servlet 映射),并使您已经拥有的 servlet 的代码工作。

主要问题是您重写了onStartup 方法,基本上破坏了AbstractAnnotationConfigDispatcherServletInitializer 的所有功能。这已经为您创建了 ContextLoaderListenerDispatcherServlet

【讨论】:

  • 太棒了!!通过在 getRootConfigClasses() 中声明 webapp 和核心配置,现在 servlet 上下文不再为空,我可以将核心服务注入控制器。非常感谢!
  • 您的网络应用不应该是根配置的一部分!这应该是 servlet 配置的一部分。我真的希望您没有同时执行这两项操作,因为这意味着您要加载应用程序的一部分!。
猜你喜欢
  • 2017-01-27
  • 2017-03-19
  • 2011-01-08
  • 2020-09-29
  • 1970-01-01
  • 2014-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多