首页 > 经济 > 正文

Spring MVC通过注解完成运行配置原理你都会吗?

来源:实战案例锦集 发布日期:2023-05-10 09:29:55 分享到:

环境:Spring5.3.26

SpringMVC使用相信大家都会使用,别人项目工程搭建后,你只需负责写Controller即可,那你是否想过自己能否把环境搭建出来呢?而且还不借助网络;本篇教大家如何通过注解快速搭建SpringMVC运行环境。


(资料图片)

传统SpringMVC配置

本节:回顾传统SpringMVC的基本配置原理。

DispatcherServlet需要一个WebApplicationContext(一个普通ApplicationContext的扩展)用于它自己的配置。WebApplicationContext有一个链接到ServletContext和它所关联的Servlet。它还绑定到ServletContext,这样应用程序就可以在需要访问WebApplicationContext时使用RequestContextUtils上的静态方法来查找它。

对于许多应用程序来说,只有一个WebApplicationContext就足够简单了。也可以有一个上下文层次结构,其中一个根WebApplicationContext在多个DispatcherServlet(或其他Servlet)实例之间共享,每个实例都有自己的子WebApplicationContext配置。有关上下文层次结构特性的更多信息,请参阅ApplicationContext的附加功能。

根WebApplicationContext通常包含基础设施bean,例如需要跨多个Servlet实例共享的数据存储库和业务服务。这些bean被有效地继承,并且可以在特定于Servlet的子WebApplicationContext中被重写(即重新声明),该子WebApplicationContext通常包含给定Servlet的本地bean。下图显示了这种关系:

web.xml中配置:

            org.springframework.web.context.ContextLoaderListener                contextConfigLocation        /WEB-INF/root-context.xml                app1        org.springframework.web.servlet.DispatcherServlet                    contextConfigLocation            /WEB-INF/app1-context.xml                1                app1        /app1/*    

ContextLoaderListener:该监听器用来创建Root 容器,该容器就是用来配置基础的Bean,如DAO,Service等。

DispatcherServlet:对应一个web 容器,也就是子容器。该容器用来配置Controller。在Controller中会应用到Service,那么该子容器就会从父容器中查找相应的Bean。如下父子关系配置:

public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {  protected WebApplicationContext initWebApplicationContext() {    // 获取父容器,该父容器是在ContextLoaderListener监听器中创建并保存到ServletContext中    WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());    WebApplicationContext wac = null;    if (this.webApplicationContext != null) {      wac = this.webApplicationContext;        if (wac instanceof ConfigurableWebApplicationContext) {          ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;          if (!cwac.isActive()) {            if (cwac.getParent() == null) {              cwac.setParent(rootContext);            }            configureAndRefreshWebApplicationContext(cwac);         }      }    }    if (wac == null) {      // 创建子容器并设置父容器      wac = createWebApplicationContext(rootContext);    }    return wac;  }}

以上就是SpringMVC的基本配置。

Servlet注册

既然是基于注解的方式配置SpringMVC,那么我们需要先了解Servlet的注册方式有哪些。

方式1:

web.xml中注册

  DemoServlet  com.pack.servlet.DemoServlet  DemoServlet  /demo

方式2:

基于注解方式

@WebServlet(name = "demoServlet", urlPatterns = "/demo")@WebServlet(value = {"/demo","/demo1"})@WebServlet(value = "/demo")@WebServlet("/demo")public class DemoServlet extends HttpServlet {  // ...}

方式3:

通过SPI技术,这也是今天要使用的方式

Servlet3.0以上的版本开始,可以通过SPI方式注册Servlet,Filter,Listener三大组件。

第一步:在项目中建立如下文件

META-INF/service/javax.servlet.ServletContainerInitializer

文件名:javax.servlet.ServletContainerInitializer

第二步:自定义类实现ServletContainerInitializer

@HandlesTypes({CustomHandler.class})public class CustomContainerInitializer implements ServletContainerInitializer {  // 这里的set集合就是当前环境中所有CustomHandler的子类  @Override  public void onStartup(Set> set, ServletContext servletContext) throws ServletException {    if (set!=null&&set.size()>0){      set.stream().forEach(cls->{        try {          CustomHandler o = (CustomHandler)cls.newInstance();          o.onStartup();        } catch (Exception e) {          e.printStackTrace();        }      });    }    //注入Servlet    ServletRegistration.Dynamic userServlet = servletContext.addServlet("DemoServlet", DemoServlet.class);    userServlet.addMapping("/demo");  }}
SpringMVC注解配置

接下来就是要使用上面介绍的Servlet注册方式的第三种方式来实现SpringMVC的注册。

在Spring中已经提供了相应的实现:

在spring-web包中:

内容:

org.springframework.web.SpringServletContainerInitializer
@HandlesTypes(WebApplicationInitializer.class)public class SpringServletContainerInitializer implements ServletContainerInitializer {}

这里我们只需要实现WebApplicationInitializer接口即可,不过Spring已经为我们定义好了该接口的抽象模版,我们只需继承该抽象类即可:

public class SpringMVCConfig extends AbstractAnnotationConfigDispatcherServletInitializer {  @Override  protected Class[] getRootConfigClasses() {    return new Class[] {RootConfig.class} ;  }  @Override  protected Class[] getServletConfigClasses() {    return new Class[] {WebConfig.class} ;  }  @Override  protected String[] getServletMappings() {    return new String[] {"/"} ;  }}

RootConfig.java

@Configurationpublic class RootConfig {}

WebConfig.java

@Configuration@ComponentScan(basePackages = {"com.pack.controller"})public class WebConfig {  }

测试controller

@RestController@RequestMapping("/demo")public class DemoController {  @GetMapping("")  public Object index() {    Map result = new HashMap<>() ;    result.put("code", 0) ;    result.put("data", "你好") ;    return result ;  }  }

测试:

只是通过如上配置,SpringMVC环境基本上是可以使用了,但是我们看上面Controller接口,是基于REST full,所以当你访问该接口时会出现如下错误:

这是因为默认情况下RequestMappingHandlerAdapter无法处理,服务器端无法提供与Accept-Charset以及Accept-Language消息头指定的值相匹配的响应。

这时候就需要为其配置相应的消息转换器:

@Beanpublic RequestMappingHandlerAdapter requestMappingHandlerAdapter() {  RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter() ;  adapter.getMessageConverters().add(new MappingJackson2HttpMessageConverter()) ;  return adapter ;}

再次方法正常:

完毕!!!

关键词:

x 广告

Spring MVC通过注解完成运行配置原理你都会吗?

环境:Spring5 3 26SpringMVC使用相信大家都会使用,别人项目工程搭建后,你只需负责写Controller即可,那你

夫妇以上恋人未满_真实恋人17分钟h试听_天天滚动

1、楼主你好,很高兴能帮到你。2、百度知道是个帮助大家的平台,但在帮助你之前,是不是应该把问题讲清楚,

环球滚动:净月潭国家级风景名胜区基础设施改造工程启动

为营造优质舒适的旅游环境,提升游客旅游体验感和满意度,净月潭国家级风景名胜区启动基础设施提升改造项目

章源钨业:目前钨精矿价格到达近期高位,公司继续看好钨价走势

章源钨业近期接受投资者调研时称,目前钨精矿价格到达近期高位,2023年中国经济呈现复苏预期,公司继续看好

世界即时看!三相电动机的转子和定子要同时通电才能工作其原因是什么_三相电动机的转子和定子要同时通电才能工作

1、三相异步电动机只有定子通电。2、转子不用通电(感应产生电)。3、就能旋转工作。本文分享完毕,希望对

观察:“拜登把国家的信用卡给刷爆了” 美国两党争斗加剧债务上限困局!耶伦连续两天发声,警告债务违约后果

“拜登把国家的信用卡给刷爆了”美国两党争斗加剧债务上限困局!耶伦连续两天发声,警告债务违约后果,共和

这些女人最容易被男人耍

第一种,经济困难的女人。这年头,没钱真的什么事情也干不了。虽然说钱很俗,但是你不能不说。经济困难的女

新资讯:魏俊邦_关于魏俊邦简述

小伙伴们,你们好,今天小夏来聊聊一篇关于魏俊邦,关于魏俊邦简述的文章,网友们对这件事情都比较关注,那

x 广告

Copyright   2015-2022 东方海洋网版权所有  备案号:沪ICP备2020036824号-8   联系邮箱:562 66 29@qq.com