成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring MVC通過注解完成運(yùn)行配置,原理你都會(huì)嗎?

開發(fā) 前端
DispatcherServlet需要一個(gè)WebApplicationContext(一個(gè)普通ApplicationContext的擴(kuò)展)用于它自己的配置。WebApplicationContext有一個(gè)鏈接到ServletContext和它所關(guān)聯(lián)的Servlet。

環(huán)境:Spring5.3.26

SpringMVC使用相信大家都會(huì)使用,別人項(xiàng)目工程搭建后,你只需負(fù)責(zé)寫Controller即可,那你是否想過自己能否把環(huán)境搭建出來呢?而且還不借助網(wǎng)絡(luò);本篇教大家如何通過注解快速搭建SpringMVC運(yùn)行環(huán)境。

傳統(tǒng)SpringMVC配置

本節(jié):回顧傳統(tǒng)SpringMVC的基本配置原理。

DispatcherServlet需要一個(gè)WebApplicationContext(一個(gè)普通ApplicationContext的擴(kuò)展)用于它自己的配置。WebApplicationContext有一個(gè)鏈接到ServletContext和它所關(guān)聯(lián)的Servlet。它還綁定到ServletContext,這樣應(yīng)用程序就可以在需要訪問WebApplicationContext時(shí)使用RequestContextUtils上的靜態(tài)方法來查找它。

對(duì)于許多應(yīng)用程序來說,只有一個(gè)WebApplicationContext就足夠簡(jiǎn)單了。也可以有一個(gè)上下文層次結(jié)構(gòu),其中一個(gè)根WebApplicationContext在多個(gè)DispatcherServlet(或其他Servlet)實(shí)例之間共享,每個(gè)實(shí)例都有自己的子WebApplicationContext配置。有關(guān)上下文層次結(jié)構(gòu)特性的更多信息,請(qǐng)參閱ApplicationContext的附加功能。

根WebApplicationContext通常包含基礎(chǔ)設(shè)施bean,例如需要跨多個(gè)Servlet實(shí)例共享的數(shù)據(jù)存儲(chǔ)庫和業(yè)務(wù)服務(wù)。這些bean被有效地繼承,并且可以在特定于Servlet的子WebApplicationContext中被重寫(即重新聲明),該子WebApplicationContext通常包含給定Servlet的本地bean。下圖顯示了這種關(guān)系:

圖片

web.xml中配置:

<web-app>


    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>


    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value>
    </context-param>


    <servlet>
        <servlet-name>app1</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/app1-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>


    <servlet-mapping>
        <servlet-name>app1</servlet-name>
        <url-pattern>/app1/*</url-pattern>
    </servlet-mapping>


</web-app>

ContextLoaderListener:該監(jiān)聽器用來創(chuàng)建Root 容器,該容器就是用來配置基礎(chǔ)的Bean,如DAO,Service等。

DispatcherServlet:對(duì)應(yīng)一個(gè)web 容器,也就是子容器。該容器用來配置Controller。在Controller中會(huì)應(yīng)用到Service,那么該子容器就會(huì)從父容器中查找相應(yīng)的Bean。如下父子關(guān)系配置:

public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
  protected WebApplicationContext initWebApplicationContext() {
    // 獲取父容器,該父容器是在ContextLoaderListener監(jiān)聽器中創(chuàng)建并保存到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) {
      // 創(chuàng)建子容器并設(shè)置父容器
      wac = createWebApplicationContext(rootContext);
    }
    return wac;
  }
}

以上就是SpringMVC的基本配置。

Servlet注冊(cè)

既然是基于注解的方式配置SpringMVC,那么我們需要先了解Servlet的注冊(cè)方式有哪些。

方式1:

web.xml中注冊(cè)

<servlet>
  <servlet-name>DemoServlet</servlet-name>
  <servlet-class>com.pack.servlet.DemoServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>DemoServlet</servlet-name>
  <url-pattern>/demo</url-pattern>
</servlet-mapping>

方式2:

基于注解方式

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

方式3:

通過SPI技術(shù),這也是今天要使用的方式

Servlet3.0以上的版本開始,可以通過SPI方式注冊(cè)Servlet,F(xiàn)ilter,Listener三大組件。

第一步:在項(xiàng)目中建立如下文件

META-INF/service/javax.servlet.ServletContainerInitializer

文件名:javax.servlet.ServletContainerInitializer

第二步:自定義類實(shí)現(xiàn)ServletContainerInitializer

@HandlesTypes({CustomHandler.class})
public class CustomContainerInitializer implements ServletContainerInitializer {
  // 這里的set集合就是當(dāng)前環(huán)境中所有CustomHandler的子類
  @Override
  public void onStartup(Set<Class<?>> 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注冊(cè)方式的第三種方式來實(shí)現(xiàn)SpringMVC的注冊(cè)。

在Spring中已經(jīng)提供了相應(yīng)的實(shí)現(xiàn):

在spring-web包中:

圖片


內(nèi)容:

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

這里我們只需要實(shí)現(xiàn)WebApplicationInitializer接口即可,不過Spring已經(jīng)為我們定義好了該接口的抽象模版,我們只需繼承該抽象類即可:

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

@Configuration
public class RootConfig {
}

WebConfig.java

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

測(cè)試controller

@RestController
@RequestMapping("/demo")
public class DemoController {


  @GetMapping("")
  public Object index() {
    Map<String, Object> result = new HashMap<>() ;
    result.put("code", 0) ;
    result.put("data", "你好") ;
    return result ;
  }
  
}

測(cè)試:

只是通過如上配置,SpringMVC環(huán)境基本上是可以使用了,但是我們看上面Controller接口,是基于REST full,所以當(dāng)你訪問該接口時(shí)會(huì)出現(xiàn)如下錯(cuò)誤:

圖片

這是因?yàn)槟J(rèn)情況下RequestMappingHandlerAdapter無法處理,服務(wù)器端無法提供與 Accept-Charset 以及 Accept-Language 消息頭指定的值相匹配的響應(yīng)。

這時(shí)候就需要為其配置相應(yīng)的消息轉(zhuǎn)換器:

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

再次方法正常:

圖片

完畢!!!

責(zé)任編輯:武曉燕 來源: 實(shí)戰(zhàn)案例錦集
相關(guān)推薦

2009-09-27 14:01:29

Spring MVC

2022-06-28 14:57:09

FormatterSpring

2021-10-31 19:39:11

注解Spring 核心類

2023-10-23 10:43:24

SpringRestful風(fēng)格

2023-05-05 07:39:04

Spring事務(wù)面試

2013-05-03 10:04:16

WorkstationvSphere

2020-08-23 10:03:51

SynchronizeJava

2009-06-19 11:43:59

Spring MVC框

2009-06-19 11:28:45

2025-06-09 01:01:00

2022-01-05 08:53:13

Spring原理分析MVC

2021-07-28 07:53:19

配置Bean掃描

2019-09-03 09:19:34

CPU架構(gòu)內(nèi)核

2020-12-29 16:55:44

ZooKeeper運(yùn)維數(shù)據(jù)結(jié)構(gòu)

2009-06-24 16:01:28

Spring MVC

2020-06-17 11:42:50

異常解析器Spring MVC

2010-08-29 21:09:57

DHCP協(xié)議

2021-01-11 15:02:27

Redis數(shù)據(jù)庫命令

2022-05-30 11:17:44

Spring容器配置

2020-07-27 16:10:49

SpringBoottomcaJava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 性高湖久久久久久久久3小时 | 福利视频网 | 黄色一级电影免费观看 | 亚洲综合无码一区二区 | 国产一区二区三区在线观看免费 | 亚洲日日夜夜 | 日韩成人 | 国产一区二区高清在线 | 欧美成人手机在线 | 午夜视频在线观看一区二区 | 天堂av中文在线 | 亚洲a毛片| 18性欧美| 久久久久网站 | 韩国精品在线 | 男人天堂av网 | 99久久精品免费看国产免费软件 | 一级黄在线观看 | 国产剧情久久 | 97成人在线 | 91精品久久久久久久久中文字幕 | 欧美福利 | 九九久视频| 中日韩欧美一级片 | 日韩精品免费在线观看 | 亚洲3p| 亚洲视频一区在线 | 色婷婷av一区二区三区软件 | 伊人伊成久久人综合网站 | 超黄毛片 | 国产日韩一区二区三区 | 欧州一区二区三区 | 国产区视频在线观看 | 视频一区二区在线观看 | 国产精品视频在线播放 | 日本在线视频一区二区 | 97超碰人人| 国产一区二 | 国产一区不卡 | 午夜精品一区二区三区在线观看 | 欧美性猛交一区二区三区精品 |