• 【Java Web开发学习】Spring MVC 开始配置


    Spring MVC 开始配置

    转载:http://www.cnblogs.com/yangchongxing/p/8871370.htm

    学习搭建最简单的Spring MVC框架。

    ===============================================================l

    目录

    1. Java配置方式
    2. Xml配置方式

    ================================================================

    Jar包下载地址:http://repo.spring.io/release/org/springframework/spring/4.3.9.RELEASE/spring-framework-4.3.9.RELEASE-dist.zip

    新建动态web工程ycxfw(名字根据实际情况定), 复制下面的jar到WebContentWEB-INFlib目录

    commons-logging-1.2.jar
    spring-aop-4.3.9.RELEASE.jar
    spring-aspects-4.3.9.RELEASE.jar
    spring-beans-4.3.9.RELEASE.jar
    spring-context-4.3.9.RELEASE.jar
    spring-context-support-4.3.9.RELEASE.jar
    spring-core-4.3.9.RELEASE.jar
    spring-expression-4.3.9.RELEASE.jar
    spring-instrument-4.3.9.RELEASE.jar
    spring-jdbc-4.3.9.RELEASE.jar
    spring-jms-4.3.9.RELEASE.jar
    spring-messaging-4.3.9.RELEASE.jar
    spring-orm-4.3.9.RELEASE.jar
    spring-oxm-4.3.9.RELEASE.jar
    spring-test-4.3.9.RELEASE.jar
    spring-tx-4.3.9.RELEASE.jar
    spring-web-4.3.9.RELEASE.jar
    spring-webmvc-4.3.9.RELEASE.jar
    spring-websocket-4.3.9.RELEASE.jar

    1、基于Java配置(推荐)

    借助Servlet3规范和Spring3.1,我们可以不用web.xml就能配置DispatchServlet

    package cn.ycx.web.config;
    
    import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
    
    public class ServletWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class<?>[] {RootConfig.class}; //ContextLoaderListener上下文配置
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[] {ServletConfig.class}; //DispatcherServlet上下文配置
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"}; //将DispatcherServlet映射到 /
        }
    
    }
    package cn.ycx.web.config;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.context.annotation.ComponentScan.Filter;
    
    @Configuration
    @ComponentScan(
            basePackages = {"cn.ycx.web"},
            // 排除掉
            excludeFilters = {@Filter( type=FilterType.ANNOTATION, value={org.springframework.stereotype.Controller.class} )} 
            )
    public class RootConfig {
    
    }
    package cn.ycx.web.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.context.support.ResourceBundleMessageSource;
    import org.springframework.web.servlet.ViewResolver;
    import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    
    @Configuration
    @EnableWebMvc
    @ComponentScan(
            basePackages = {"cn.ycx.web.controller"},
            // 仅仅扫描
            includeFilters = {@Filter( type=FilterType.ANNOTATION, value={org.springframework.stereotype.Controller.class} )}
            )
    public class ServletConfig extends WebMvcConfigurerAdapter {
        /**
         * 配置JSP视图解析器
         * @return
         */
        @Bean
        public ViewResolver viewResolver() {
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("/WEB-INF/views");
            resolver.setSuffix(".jsp");
            resolver.setExposeContextBeansAsAttributes(true);
            return resolver;
        }
        /**
         * 配置静态文件处理
         */
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    }

    新建WebContentWEB-INFviews estindex.jsp文件

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    Test page index jsp
    </body>
    </html>

    启动tomcat服务器访问,http://127.0.0.1:8080/ycxfw/test/index。

    到此代码已经写完了。

    @Configuration 注解表示该bean是一个配置文件,Spring自动加载其中的bean

    @EnableWebMvc 注解表示启用Spring Mvc

    @ComponentScan 注解表示自动扫描要装配的bean,basePackages是要扫描的目录,默认扫描配置文件所在的包及子包;includeFilters 包含过滤,excludeFilters 排除过滤

    ServletConfig配置Spring MVC相关的bean(相当于DispatcherServlet的配置),RootConfig配置spring相关的bean(相当于ContextLoaderListener的配置

    有同学可能对没有web.xml文件而疑惑,我们来说说原因。

    javax.servlet.ServletContainerInitializer是Servlet 3.0 新增的一个接口类,容器在启动时使用JAR Service API来发现ServletContainerInitializer的实现类,并且容器将WEB-INF/lib目录下JAR包中的类都交给该类的onStartup()方法处理,我们通常需要在该实现类上使用 @HandlesTypes 注解来指定希望被处理的类,过滤掉不希望给 onStartup()处理的类。

    * Licensed to the Apache Software Foundation (ASF) under one or more
    package javax.servlet;
    
    import java.util.Set;
    
    /**
     * ServletContainerInitializers (SCIs) are registered via an entry in the
     * file META-INF/services/javax.servlet.ServletContainerInitializer that must be
     * included in the JAR file that contains the SCI implementation.
     * <p>
     * SCI processing is performed regardless of the setting of metadata-complete.
     * SCI processing can be controlled per JAR file via fragment ordering. If an
     * absolute ordering is defined, the only those JARs included in the ordering
     * will be processed for SCIs. To disable SCI processing completely, an empty
     * absolute ordering may be defined.
     * <p>
     * SCIs register an interest in annotations (class, method or field) and/or
     * types via the {@link javax.servlet.annotation.HandlesTypes} annotation which
     * is added to the class.
     *
     * @since Servlet 3.0
     */
    public interface ServletContainerInitializer {
    
        /**
         * Receives notification during startup of a web application of the classes
         * within the web application that matched the criteria defined via the
         * {@link javax.servlet.annotation.HandlesTypes} annotation.
         *
         * @param c     The (possibly null) set of classes that met the specified
         *              criteria
         * @param ctx   The ServletContext of the web application in which the
         *              classes were discovered
         *
         * @throws ServletException If an error occurs
         */
        void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException;
    }

    也就是说容器自动发现实现ServletContainerInitializer接口的类,如果能发现的话,就会用它来配置Servlet容器,Spring提供了这个接口的实现 SpringServletContainerInitializer

    /*
     * Copyright 2002-2016 the original author or authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package org.springframework.web;
    
    import java.lang.reflect.Modifier;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.ServiceLoader;
    import java.util.Set;
    import javax.servlet.ServletContainerInitializer;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.HandlesTypes;
    
    import org.springframework.core.annotation.AnnotationAwareOrderComparator;
    
    /**
     * Servlet 3.0 {@link ServletContainerInitializer} designed to support code-based
     * configuration of the servlet container using Spring's {@link WebApplicationInitializer}
     * SPI as opposed to (or possibly in combination with) the traditional
     * {@code web.xml}-based approach.
     *
     * <h2>Mechanism of Operation</h2>
     * This class will be loaded and instantiated and have its {@link #onStartup}
     * method invoked by any Servlet 3.0-compliant container during container startup assuming
     * that the {@code spring-web} module JAR is present on the classpath. This occurs through
     * the JAR Services API {@link ServiceLoader#load(Class)} method detecting the
     * {@code spring-web} module's {@code META-INF/services/javax.servlet.ServletContainerInitializer}
     * service provider configuration file. See the
     * <a href="http://download.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider">
     * JAR Services API documentation</a> as well as section <em>8.2.4</em> of the Servlet 3.0
     * Final Draft specification for complete details.
     *
     * <h3>In combination with {@code web.xml}</h3>
     * A web application can choose to limit the amount of classpath scanning the Servlet
     * container does at startup either through the {@code metadata-complete} attribute in
     * {@code web.xml}, which controls scanning for Servlet annotations or through an
     * {@code <absolute-ordering>} element also in {@code web.xml}, which controls which
     * web fragments (i.e. jars) are allowed to perform a {@code ServletContainerInitializer}
     * scan. When using this feature, the {@link SpringServletContainerInitializer}
     * can be enabled by adding "spring_web" to the list of named web fragments in
     * {@code web.xml} as follows:
     *
     * <pre class="code">
     * {@code
     * <absolute-ordering>
     *   <name>some_web_fragment</name>
     *   <name>spring_web</name>
     * </absolute-ordering>
     * }</pre>
     *
     * <h2>Relationship to Spring's {@code WebApplicationInitializer}</h2>
     * Spring's {@code WebApplicationInitializer} SPI consists of just one method:
     * {@link WebApplicationInitializer#onStartup(ServletContext)}. The signature is intentionally
     * quite similar to {@link ServletContainerInitializer#onStartup(Set, ServletContext)}:
     * simply put, {@code SpringServletContainerInitializer} is responsible for instantiating
     * and delegating the {@code ServletContext} to any user-defined
     * {@code WebApplicationInitializer} implementations. It is then the responsibility of
     * each {@code WebApplicationInitializer} to do the actual work of initializing the
     * {@code ServletContext}. The exact process of delegation is described in detail in the
     * {@link #onStartup onStartup} documentation below.
     *
     * <h2>General Notes</h2>
     * In general, this class should be viewed as <em>supporting infrastructure</em> for
     * the more important and user-facing {@code WebApplicationInitializer} SPI. Taking
     * advantage of this container initializer is also completely <em>optional</em>: while
     * it is true that this initializer will be loaded and invoked under all Servlet 3.0+
     * runtimes, it remains the user's choice whether to make any
     * {@code WebApplicationInitializer} implementations available on the classpath. If no
     * {@code WebApplicationInitializer} types are detected, this container initializer will
     * have no effect.
     *
     * <p>Note that use of this container initializer and of {@code WebApplicationInitializer}
     * is not in any way "tied" to Spring MVC other than the fact that the types are shipped
     * in the {@code spring-web} module JAR. Rather, they can be considered general-purpose
     * in their ability to facilitate convenient code-based configuration of the
     * {@code ServletContext}. In other words, any servlet, listener, or filter may be
     * registered within a {@code WebApplicationInitializer}, not just Spring MVC-specific
     * components.
     *
     * <p>This class is neither designed for extension nor intended to be extended.
     * It should be considered an internal type, with {@code WebApplicationInitializer}
     * being the public-facing SPI.
     *
     * <h2>See Also</h2>
     * See {@link WebApplicationInitializer} Javadoc for examples and detailed usage
     * recommendations.<p>
     *
     * @author Chris Beams
     * @author Juergen Hoeller
     * @author Rossen Stoyanchev
     * @since 3.1
     * @see #onStartup(Set, ServletContext)
     * @see WebApplicationInitializer
     */
    @HandlesTypes(WebApplicationInitializer.class)
    public class SpringServletContainerInitializer implements ServletContainerInitializer {
    
        /**
         * Delegate the {@code ServletContext} to any {@link WebApplicationInitializer}
         * implementations present on the application classpath.
         * <p>Because this class declares @{@code HandlesTypes(WebApplicationInitializer.class)},
         * Servlet 3.0+ containers will automatically scan the classpath for implementations
         * of Spring's {@code WebApplicationInitializer} interface and provide the set of all
         * such types to the {@code webAppInitializerClasses} parameter of this method.
         * <p>If no {@code WebApplicationInitializer} implementations are found on the classpath,
         * this method is effectively a no-op. An INFO-level log message will be issued notifying
         * the user that the {@code ServletContainerInitializer} has indeed been invoked but that
         * no {@code WebApplicationInitializer} implementations were found.
         * <p>Assuming that one or more {@code WebApplicationInitializer} types are detected,
         * they will be instantiated (and <em>sorted</em> if the @{@link
         * org.springframework.core.annotation.Order @Order} annotation is present or
         * the {@link org.springframework.core.Ordered Ordered} interface has been
         * implemented). Then the {@link WebApplicationInitializer#onStartup(ServletContext)}
         * method will be invoked on each instance, delegating the {@code ServletContext} such
         * that each instance may register and configure servlets such as Spring's
         * {@code DispatcherServlet}, listeners such as Spring's {@code ContextLoaderListener},
         * or any other Servlet API componentry such as filters.
         * @param webAppInitializerClasses all implementations of
         * {@link WebApplicationInitializer} found on the application classpath
         * @param servletContext the servlet context to be initialized
         * @see WebApplicationInitializer#onStartup(ServletContext)
         * @see AnnotationAwareOrderComparator
         */
        @Override
        public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
                throws ServletException {
    
            List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();
    
            if (webAppInitializerClasses != null) {
                for (Class<?> waiClass : webAppInitializerClasses) {
                    // Be defensive: Some servlet containers provide us with invalid classes,
                    // no matter what @HandlesTypes says...
                    if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
                            WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                        try {
                            initializers.add((WebApplicationInitializer) waiClass.newInstance());
                        }
                        catch (Throwable ex) {
                            throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
                        }
                    }
                }
            }
    
            if (initializers.isEmpty()) {
                servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
                return;
            }
    
            servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
            AnnotationAwareOrderComparator.sort(initializers);
            for (WebApplicationInitializer initializer : initializers) {
                initializer.onStartup(servletContext);
            }
        }
    
    }

    这个类又会反过来查找实现WebApplicationInitializer的类并将配置的任务交给他们来完成。

    我们来看看继承关系,我们自己的类ServletWebApplicationInitializer

    继承AbstractAnnotationConfigDispatcherServletInitializer继承AbstractDispatcherServletInitializer继承AbstractContextLoaderInitializer继承WebApplicationInitializer

    /*
     * Copyright 2002-2012 the original author or authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package org.springframework.web;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    
    /**
     * Interface to be implemented in Servlet 3.0+ environments in order to configure the
     * {@link ServletContext} programmatically -- as opposed to (or possibly in conjunction
     * with) the traditional {@code web.xml}-based approach.
     *
     * <p>Implementations of this SPI will be detected automatically by {@link
     * SpringServletContainerInitializer}, which itself is bootstrapped automatically
     * by any Servlet 3.0 container. See {@linkplain SpringServletContainerInitializer its
     * Javadoc} for details on this bootstrapping mechanism.
     *
     * <h2>Example</h2>
     * <h3>The traditional, XML-based approach</h3>
     * Most Spring users building a web application will need to register Spring's {@code
     * DispatcherServlet}. For reference, in WEB-INF/web.xml, this would typically be done as
     * follows:
     * <pre class="code">
     * {@code
     * <servlet>
     *   <servlet-name>dispatcher</servlet-name>
     *   <servlet-class>
     *     org.springframework.web.servlet.DispatcherServlet
     *   </servlet-class>
     *   <init-param>
     *     <param-name>contextConfigLocation</param-name>
     *     <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
     *   </init-param>
     *   <load-on-startup>1</load-on-startup>
     * </servlet>
     *
     * <servlet-mapping>
     *   <servlet-name>dispatcher</servlet-name>
     *   <url-pattern>/</url-pattern>
     * </servlet-mapping>}</pre>
     *
     * <h3>The code-based approach with {@code WebApplicationInitializer}</h3>
     * Here is the equivalent {@code DispatcherServlet} registration logic,
     * {@code WebApplicationInitializer}-style:
     * <pre class="code">
     * public class MyWebAppInitializer implements WebApplicationInitializer {
     *
     *    &#064;Override
     *    public void onStartup(ServletContext container) {
     *      XmlWebApplicationContext appContext = new XmlWebApplicationContext();
     *      appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
     *
     *      ServletRegistration.Dynamic dispatcher =
     *        container.addServlet("dispatcher", new DispatcherServlet(appContext));
     *      dispatcher.setLoadOnStartup(1);
     *      dispatcher.addMapping("/");
     *    }
     *
     * }</pre>
     *
     * As an alternative to the above, you can also extend from {@link
     * org.springframework.web.servlet.support.AbstractDispatcherServletInitializer}.
     *
     * As you can see, thanks to Servlet 3.0's new {@link ServletContext#addServlet} method
     * we're actually registering an <em>instance</em> of the {@code DispatcherServlet}, and
     * this means that the {@code DispatcherServlet} can now be treated like any other object
     * -- receiving constructor injection of its application context in this case.
     *
     * <p>This style is both simpler and more concise. There is no concern for dealing with
     * init-params, etc, just normal JavaBean-style properties and constructor arguments. You
     * are free to create and work with your Spring application contexts as necessary before
     * injecting them into the {@code DispatcherServlet}.
     *
     * <p>Most major Spring Web components have been updated to support this style of
     * registration.  You'll find that {@code DispatcherServlet}, {@code FrameworkServlet},
     * {@code ContextLoaderListener} and {@code DelegatingFilterProxy} all now support
     * constructor arguments. Even if a component (e.g. non-Spring, other third party) has not
     * been specifically updated for use within {@code WebApplicationInitializers}, they still
     * may be used in any case. The Servlet 3.0 {@code ServletContext} API allows for setting
     * init-params, context-params, etc programmatically.
     *
     * <h2>A 100% code-based approach to configuration</h2>
     * In the example above, {@code WEB-INF/web.xml} was successfully replaced with code in
     * the form of a {@code WebApplicationInitializer}, but the actual
     * {@code dispatcher-config.xml} Spring configuration remained XML-based.
     * {@code WebApplicationInitializer} is a perfect fit for use with Spring's code-based
     * {@code @Configuration} classes. See @{@link
     * org.springframework.context.annotation.Configuration Configuration} Javadoc for
     * complete details, but the following example demonstrates refactoring to use Spring's
     * {@link org.springframework.web.context.support.AnnotationConfigWebApplicationContext
     * AnnotationConfigWebApplicationContext} in lieu of {@code XmlWebApplicationContext}, and
     * user-defined {@code @Configuration} classes {@code AppConfig} and
     * {@code DispatcherConfig} instead of Spring XML files. This example also goes a bit
     * beyond those above to demonstrate typical configuration of the 'root' application
     * context and registration of the {@code ContextLoaderListener}:
     * <pre class="code">
     * public class MyWebAppInitializer implements WebApplicationInitializer {
     *
     *    &#064;Override
     *    public void onStartup(ServletContext container) {
     *      // Create the 'root' Spring application context
     *      AnnotationConfigWebApplicationContext rootContext =
     *        new AnnotationConfigWebApplicationContext();
     *      rootContext.register(AppConfig.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("/");
     *    }
     *
     * }</pre>
     *
     * As an alternative to the above, you can also extend from {@link
     * org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer}.
     *
     * Remember that {@code WebApplicationInitializer} implementations are <em>detected
     * automatically</em> -- so you are free to package them within your application as you
     * see fit.
     *
     * <h2>Ordering {@code WebApplicationInitializer} execution</h2>
     * {@code WebApplicationInitializer} implementations may optionally be annotated at the
     * class level with Spring's @{@link org.springframework.core.annotation.Order Order}
     * annotation or may implement Spring's {@link org.springframework.core.Ordered Ordered}
     * interface. If so, the initializers will be ordered prior to invocation. This provides
     * a mechanism for users to ensure the order in which servlet container initialization
     * occurs. Use of this feature is expected to be rare, as typical applications will likely
     * centralize all container initialization within a single {@code WebApplicationInitializer}.
     *
     * <h2>Caveats</h2>
     *
     * <h3>web.xml versioning</h3>
     * <p>{@code WEB-INF/web.xml} and {@code WebApplicationInitializer} use are not mutually
     * exclusive; for example, web.xml can register one servlet, and a {@code
     * WebApplicationInitializer} can register another. An initializer can even
     * <em>modify</em> registrations performed in {@code web.xml} through methods such as
     * {@link ServletContext#getServletRegistration(String)}. <strong>However, if
     * {@code WEB-INF/web.xml} is present in the application, its {@code version} attribute
     * must be set to "3.0" or greater, otherwise {@code ServletContainerInitializer}
     * bootstrapping will be ignored by the servlet container.</strong>
     *
     * <h3>Mapping to '/' under Tomcat</h3>
     * <p>Apache Tomcat maps its internal {@code DefaultServlet} to "/", and on Tomcat versions
     * &lt;= 7.0.14, this servlet mapping <em>cannot be overridden programmatically</em>.
     * 7.0.15 fixes this issue. Overriding the "/" servlet mapping has also been tested
     * successfully under GlassFish 3.1.<p>
     *
     * @author Chris Beams
     * @since 3.1
     * @see SpringServletContainerInitializer
     * @see org.springframework.web.context.AbstractContextLoaderInitializer
     * @see org.springframework.web.servlet.support.AbstractDispatcherServletInitializer
     * @see org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
     */
    public interface WebApplicationInitializer {
    
        /**
         * Configure the given {@link ServletContext} with any servlets, filters, listeners
         * context-params and attributes necessary for initializing this web application. See
         * examples {@linkplain WebApplicationInitializer above}.
         * @param servletContext the {@code ServletContext} to initialize
         * @throws ServletException if any call against the given {@code ServletContext}
         * throws a {@code ServletException}
         */
        void onStartup(ServletContext servletContext) throws ServletException;
    
    }

    所以在容器启动时就会自动找到我们的初始化类ServletWebApplicationInitializer

    @Configuration 注解特别说明

    我们要是有多个配置文件,他们之间如何相互引用呢?答案就是使用@Import注解,比如我们有DataSourceConfig配置,想要在RootConfig配置中引用,代码如下。

    package cn.ycx.config;
    
    import javax.sql.DataSource;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ComponentScan.Filter;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.FilterType;
    import org.springframework.context.annotation.Import;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.web.multipart.MultipartResolver;
    import org.springframework.web.multipart.support.StandardServletMultipartResolver;
    
    @Configuration
    @ComponentScan(basePackages = {"cn.ycx"}, excludeFilters = {
            @Filter( type=FilterType.ANNOTATION, value=org.springframework.stereotype.Controller.class)
            })
    @Import(DataSourceConfig.class) //引用其他配置中的Bean
    public class RootConfig {
        @Bean
        public MultipartResolver multipartResolver() {
            System.out.println("multipartResolver...");
            return new StandardServletMultipartResolver();
        }
        @Bean
        public JdbcTemplate jdbcTemplate(DataSource dataSource) {
            System.out.println("jdbcTemplate...");
            return new JdbcTemplate(dataSource);
        }
    }
    package cn.ycx.config;
    
    import javax.naming.NamingException;
    import javax.sql.DataSource;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.jndi.JndiObjectFactoryBean;
    
    public class DataSourceConfig {
        @Bean
        public DataSource dataSource() throws IllegalArgumentException, NamingException {
            System.out.println("dataSource...");
            JndiObjectFactoryBean jndi = new JndiObjectFactoryBean();
            jndi.setJndiName("jdbc/mysql");
            jndi.setResourceRef(true);//自动添加 java:comp/env/ 前缀
            jndi.setProxyInterface(javax.sql.DataSource.class);
            jndi.afterPropertiesSet();
            return (DataSource) jndi.getObject();
        }    
    }

    注意DataSourceConfig没有加@Configuration注解

     2、Xml配置方式

    这种方式很简单,主要是配置web.xml和servlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
      <display-name>web</display-name>
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      <context-param>
        <param-name>spring.profiles.default</param-name>
        <param-value>dev</param-value>
      </context-param>
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INFcontext.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      <servlet>
        <servlet-name>ds</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>WEB-INFservlet.xml</param-value>
        </init-param>
        <init-param>
          <param-name>spring.profiles.default</param-name>
          <param-value>dev</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>ds</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:c="http://www.springframework.org/schema/c"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
        
          <mvc:annotation-driven></mvc:annotation-driven>
          <context:component-scan base-package="cn.ycx"></context:component-scan>
        <mvc:default-servlet-handler />
        <!-- 会加载所有的properties文件 -->
        <context:property-placeholder/>
        <bean id="viewResolver" 
          class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
          p:prefix="/WEB-INF/views" p:suffix=".jsp"></bean>
    </beans>

    剩下的就是编写控制器

  • 相关阅读:
    理解缓慢变化维(Slowly Changing Dimension)
    分析Reporting Service的报表执行记录
    XCOPY
    Esxi主机从VC断开的怪事
    奇怪的SQLserver执行
    明细表达到15亿了
    现在才知道“quota”
    oledb读取Excel数据丢失原因
    配置subversion
    sql服务器的操作系统升级,数据库如何来迁移呢?
  • 原文地址:https://www.cnblogs.com/yangchongxing/p/8871370.html
Copyright © 2020-2023  润新知