如何使用纯基于 Java 的配置来配置 Spring MVC?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22315672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:53:55  来源:igfitidea点击:

How to configure Spring MVC with pure Java-based configuration?

javaspringspring-mvc

提问by user1902183

I have, what I would consider a pretty simple Spring MVC setup. My applicationContext.xml is this:

我有,我认为是一个非常简单的 Spring MVC 设置。我的 applicationContext.xml 是这样的:

<mvc:annotation-driven />
<mvc:resources mapping="/css/**" location="/css/" />
<context:property-placeholder location="classpath:controller-test.properties" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:prefix="/WEB-INF/views/" p:suffix=".jsp" />

My web.xml is currently this:

我的 web.xml 目前是这样的:

  <servlet>
   <servlet-name>springDispatcherServlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
  </servlet>

  <!-- Map all requests to the DispatcherServlet for handling -->
  <servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

I am trying to convert this set up to pure Java-based config. I've searched the web and so far, I've come up with stuff that explains (some what) how to do the Java config but doesn't explain how to register that Java config with the environment, i.e., the web context.

我正在尝试将此设置转换为纯基于 Java 的配置。我已经在网上搜索过,到目前为止,我已经想出了一些解释(一些什么)如何进行 Java 配置的东西,但没有解释如何将 Java 配置注册到环境中,即 web 上下文。

What I have so far in terms of @Configuration is this:

到目前为止,我在 @Configuration 方面是这样的:

 @Configuration
 @EnableWebMvc
 @PropertySource("classpath:controller.properties")
 @ComponentScan("com.project.web")
 public class WebSpringConfig extends WebMvcConfigurerAdapter {

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

 @Bean
 public ViewResolver configureViewResolver() {
     InternalResourceViewResolver viewResolve = new InternalResourceViewResolver();
     viewResolve.setPrefix("/WEB-INF/views/");
     viewResolve.setSuffix(".jsp");

     return viewResolve;
 }

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

How do I register this with the web container? I am using the latest spring (4.02).

如何在 Web 容器中注册它?我正在使用最新的 spring (4.02)。

Thanks!

谢谢!

采纳答案by Santosh Joshi

You need to make following changes to web.xmlin order to support java based configuration. This will tell the the DispatcherServletto load configuration using the annotation based java configuration AnnotationConfigWebApplicationContext. You only need to pass the location of your java config file to the contextConfigLocationparam, as below

您需要进行以下更改web.xml以支持基于 Java 的配置。这将告诉DispatcherServlet使用基于注解的 java 配置加载配置AnnotationConfigWebApplicationContext。你只需要将你的java配置文件的位置传递给contextConfigLocation参数,如下

<servlet>
  <servlet-name>springDispatcherServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
   </init-param>
   <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/*path to your WebSpringConfig*/ </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

Update: Doing the same without making changes to web.xml

更新:在不更改 web.xml 的情况下执行相同操作

You can even do this without web.xmlas Servlet Specification 3.0 makes the web.xmloptional. You only need to implement/configure WebApplicationInitializerinterface to configure the ServletContextwhich will allow you to create, configure, and perform registration of DispatcherServletprogrammatically. The good thing is that WebApplicationInitializeris detected automatically.

您甚至可以在没有web.xmlServlet 规范 3.0 的情况下执行此操作web.xml。您只需要实现/配置WebApplicationInitializer接口来配置ServletContext它将允许您以DispatcherServlet编程方式创建、配置和执行注册。好处是可以WebApplicationInitializer自动检测。

In summary, one needs to implement WebApplicationInitializerto get rid of web.xml.

总之,需要实施WebApplicationInitializer以摆脱web.xml.

 public class MyWebAppInitializer implements WebApplicationInitializer {

 @Override
 public void onStartup(ServletContext container) {
  // Create the 'root' Spring application context
  AnnotationConfigWebApplicationContext rootContext =
                       new AnnotationConfigWebApplicationContext();
  rootContext.register(WebSpringConfig.class);

  // Manage the lifecycle of the root application context
  container.addListener(new ContextLoaderListener(rootContext));

  // Create the dispatcher servlet's Spring application context
  AnnotationConfigWebApplicationContext dispatcherContext =
                     new AnnotationConfigWebApplicationContext();
  dispatcherContext.register(DispatcherConfig.class);

  // Register and map the dispatcher servlet
  ServletRegistration.Dynamic dispatcher =
    container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");
  }
}

Update: from comments
A slightly more convoluted explanation is also included in the official Spring reference Spring 4 Release

更新:来自评论
官方 Spring 参考Spring 4 Release 中还包含稍微复杂的解释

Reference:

参考:

http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html

http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html

回答by Yash

Java-based configurationwithout adding any elements to web.xml. WebApplicationInitializeris a perfect fit for use with Spring's code-based @Configurationclasses

基于 Java 的配置,无需向web.xml. WebApplicationInitializer非常适合与 Spring 的基于代码的@Configuration类一起使用

WebApplicationInitializer ? Interface to be implemented in Servlet 3.0+ environmentsin order to configure the ServletContext programmatically -- as opposed to (or possibly in conjunction with) the traditional web.xml-based approach. Implementations of this SPI will be detected automatically by SpringServletContainerInitializer, which itself is bootstrapped automatically by any Servlet 3.0 container.Using Servlet Spec 3.0 of Tomcat 7

WebApplicationInitializer ? 为了以编程方式配置 ServletContext而实现的接口Servlet 3.0+ environments——与传统的基于 web.xml 的方法相反(或可能结合)。Implementations of this SPI will be detected automatically by SpringServletContainerInitializer, which itself is bootstrapped automatically by any Servlet 3.0 container. 使用 Tomcat 7 的 Servlet 规范 3.0

From Spring 3.2 some Abstract class were listed which implemented WebApplicationInitializer which will be detected automatically by the SrevletContainer.

从 Spring 3.2 开始,列出了一些抽象类,它们实现了 WebApplicationInitializer,SrevletContainer 会自动检测这些类。

AbstractAnnotationConfigDispatcherServletInitializer extends
AbstractDispatcherServletInitializer extends
AbstractContextLoaderInitializer implements WebApplicationInitializer

Using Spring 4.1.6.RELEASEversion with the modules core, web, webmvc, beans.

使用4.1.6.RELEASE带有模块的Spring版本core, web, webmvc, beans

public class WebXML_DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

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

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

}

Java-based configuration to Serve Static Resources with Spring.Spring Boot

使用 Spring 提供静态资源的基于 Java 的配置。弹簧靴

@Configuration
@EnableWebMvc // <mvc:annotation-driven />
@ComponentScan(value = {"com.github.yash777.controllers"})
// <context:component-scan base-package="com.github.yash777" />
public class MvcServletXMLConfigurer extends WebMvcConfigurerAdapter implements WebMvcConfigurer {

    /**
     * <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
     * p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
     * 
     * @return InternalResourceViewResolver as a bean configuration.
     */
    @Bean
    public InternalResourceViewResolver getInternalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        System.out.println("WebMvcConfigurer - addResourceHandlers() function get loaded...");

        // <mvc:resources mapping="/styles/**" location="/css/" />
        registry
            .addResourceHandler("/styles/**") 
            .addResourceLocations("/css/") // webapp/css/
            .setCachePeriod(3600)
            .resourceChain(true) // Spring 4.1
            .addResolver(new GzipResourceResolver()) // Spring 4.1
            .addResolver(new PathResourceResolver()); // Spring 4.1

        // <mvc:resources mapping="/static/**" location="/static/" />
        registry.addResourceHandler("/static/**")
                .addResourceLocations("/static/", "classpath:/static/") // src/main/resources/static/
                .setCachePeriod(3600)
                .resourceChain(true)
                .addResolver(new PathResourceResolver());
    }
}

Listed a sample controller:

列出了一个示例控制器:

@Controller
@RequestMapping(value = { "/controller", "/c" })
public class Test extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @RequestMapping(value = {"/message", "/m"}, method = RequestMethod.GET )
    public void message(HttpServletRequest request, HttpServletResponse response ) throws IOException {
        System.out.println("@Controller Get method called.");
    }

    @RequestMapping(value = "/getView", method = RequestMethod.GET )
    public ModelAndView setViewName( Model model ) {
        System.out.println("GET... /getView");
        ModelAndView mav = new ModelAndView();
        mav.setViewName("test");
        return mav;
    }
}

WEB-INF/web.xml

WEB-INF/web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>