zoukankan      html  css  js  c++  java
  • Spring MVC 零配置 / Spring MVC JavaConfig

    1. Spring MVC的核心就是DispatcherServlet类,Spring MVC处理请求的流程如下图所示:

    2. Spring MVC中典型的上下文层次

    当我们初始化一个DispatcherServlet类时,Spring MVC会在web应用的WEB-INF目录下查找一个名字叫:[servlet-name]-servlet.xml的配置文件,查询这个文件中定义的bean并初始化。[servlet-name]-servlet.xml的定义的bean初始化时将会覆盖在全局范围内(global scope)定义的相同名称的bean。我们一般会在web.xml中定义DispatcherServlet。由上图我们可以看出Controller、HandlerMapping、ViewResovler类(和web有关的)在Servlet WebApplicationContext中定义,而Services类,Repositories类(中间服务、数据源等)在Root WebApplicationContext中定义。

    3. Spring MVC中单个的根上下文(Single Root Contexct)

     如果只有一个单一个根上下文,这样我们就可以定义一个空的contextConfigLocation,因此所有的beans就要在这这个单一的Root Context中定义了。

    4. 如何不再要web.xm和[servlet-name].servlet.xml而采用纯粹的java类来实现?

    从上图中我们可以看出只要继承了AbstractAnnotationConfigDispatcherServletInitializer类并实现了相关方法即可实现注册一个DispatcherServlet类。

    4.1.将 DispatcherServlet 配置在 Servlet 容器中而不再使用 web.xml 。

    public class RtpFrontWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        /**
         * 指定 Root WebApplicationContext 类,这个类必须@Configuration来注解,从而代替XML配置文件
         */
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class<?>[]{RootConfig.class};
        }
    
        /**
         * 指定 Servlet WebApplicationContext 类,这个类必须@Configuration来注解,从而代替XML配置文件
         */
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[]{WebConfig.class};
        }
    
        /**
         * 指定 Servlet mappings
         */
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    }

     4.2 定义RootConfig类

    @Configuration
    @ComponentScan(basePackageClasses = Configs.class,
            excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})
    public class RootConfig {
    }

    RootConfig类使用了@Configuration作为注解,而@Configuration本身是使用了@Component进行了注解。所以这个RootConfig类是可以被组件扫描到并注入到容器中的。@Configuration用来说明这个是配置类用来替换原来的xml。了实现组件自动扫描和实例化并注入到容器中,我们要在配置类中加上@ComponnetScan注解,并设定扫描的包的范围。本示例扫描的是Configs.class类所在的包。

     4.3 定义WebConfig类

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackageClasses = HomeController.class)
    public class WebConfig {
    }

    通过@EnableMvc来导入Spring MVC的相关配置,通过@ComponentScan来自动扫描控制器类HomeController所在的包。同样,@Configuration用来说明这个是配置类用来替换原来的xml。

    5. 从Servlet容器中(Bean工厂)获取bean.

     下面是一个工具类,代码如下:

    public class SpringContextUtil {
    
        /**
         * 私有构造函数,不允许实例化
         */
        private SpringContextUtil(){
        }
    
        /**
         * Spring应用上下文环境
         */
        private static AnnotationConfigWebApplicationContext ctx;
    
        static {
            ctx = new AnnotationConfigWebApplicationContext();
            ctx.register(RootConfig.class);
            ctx.refresh();
        }
    
        /**
         * 获取指定Bean的实例
         *
         * @param name 要获取Bean的名称
         * @return Bean object
         */
        public static Object getBean(String name) {
            return ctx.getBean(name);
        }
    }

     定义了一个工具类来从servlet容器中获取bean。这些bean都是被自动扫描并注入到servlet容器中去的。默认情况下,这个bean的实例都是单例的。获取bean的方法如下:

     AtomTransaction atomTransaction = (AtomTransaction) SpringContextUtil.getBean(getBeanName(transType));

     至此,我们已经完成了Spring MVC的零配置实现,主要是用相关的Java类来代替之前的XML文件。

    总结:

    1、Spring MVC的核心是DispatcherServlet类,它主要实现请求的路由和相关流程的控制;

    2、传统DispatcherServlet类的初始化由读取web.xml和[servlet-name]-servlet.xml的相关配置来实现;

    3、为什么我们要采用annotation而非xml?基于java的配置,它比基于XML的配置更加强大、类型安全并且易于重构;

    4、零配置,其实很简单:继承AbstractAnnotationConfigDispatcherServletInitializer这个抽象类并实现3个相关的抽象方法,3个抽象方法中分别指定:Servlet WebApplicationContext(WebConfig)、Root WebApplicationContext(RootConfig)、Mappings。WebConfig和RootConfig必须要有@Configuration注解和@ComponentScan注解。@Configuration注解用来表明这些是配置类,用来替换XML;@ComponentScan注解用来实现组件或Bean的自动化扫描及在容器中注册(默认为初始化单例)。

    5、使用AnnotationConfigWebApplicationContext来从容器中获取Bean,这些Bean默认都是单例的。

    帮助到您了吗?

    打赏作者(支付宝):

  • 相关阅读:
    flutter 使用keyboard_actions 关闭ios键盘
    Android Studio androidx 包冲突解决方法
    flutter 卡在Running Gradle task 'assembleDebug'...
    SpringBoot Controller接收参数的几种常用方式
    RN 0.6以后react-navigation 导航报错null is not an object (evaluating '_RNGestureHandlerModule.default.Direction')
    flutter 调用摄像头和照片
    RN 真机roload
    iOS Undefined symbols for architecture armv7:
    android 签名生成和签名验证
    Keil MDK中Image~~RW_IRAM1~~ZI~~Limit(~表示$)
  • 原文地址:https://www.cnblogs.com/frankyou/p/6888566.html
Copyright © 2011-2022 走看看