如何使用纯Java配置Spring MVC?

2022-09-01 06:02:46

我有,我认为一个非常简单的Spring MVC设置。我的应用程序上下文.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" />

我的网络.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>

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

到目前为止,我在@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();
 }
}

如何将其注册到 Web 容器?我正在使用最新的弹簧(4.02)。

谢谢!


答案 1

您需要进行以下更改才能支持基于 java 的配置。这将告诉 使用基于注释的 java 配置加载配置 。您只需要将java配置文件的位置传递给参数,如下所示web.xmlDispatcherServletAnnotationConfigWebApplicationContextcontextConfigLocation

<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>

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

您甚至可以在没有Servlet规范3.0的情况下执行此操作。您只需要实现/配置接口即可配置,这将允许您以编程方式创建,配置和执行注册。好处是可以自动检测到。web.xmlweb.xmlWebApplicationInitializerServletContextDispatcherServletWebApplicationInitializer

总之,需要实现才能摆脱.WebApplicationInitializerweb.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("/");
  }
}

更新:来自评论
一个稍微更复杂的解释也包含在官方春季参考春季4发布

参考:

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


答案 2

基于 Java 的配置,无需向 中添加任何元素。WebApplicationInitializer非常适合与Spring基于代码的类一起使用web.xml@Configuration

WebApplication初始化器 « Servlet 3.0 +环境中实现的接口,以便以编程方式配置ServletContext - 而不是(或可能与)传统的基于web.xml的方法结合使用。SpringServletContainerInitializer 会自动检测此 SPI 的实现,它本身由任何 Servlet 3.0 容器自动引导使用 Tomcat 7 的 Servlet Spec 3.0

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

AbstractAnnotationConfigDispatcherServletInitializer extends
AbstractDispatcherServletInitializer extends
AbstractContextLoaderInitializer implements WebApplicationInitializer

使用弹簧版本与模块。4.1.6.RELEASEcore, 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 的配置,通过 Spring 为静态资源提供服务。弹簧靴

@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());
    }
}

列出了一个示例控制器:

@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

<!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>

推荐