免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      阿里跳槽來的,連Spring容器與SpringMVC的容器的區(qū)別都不知道

      說起spring容器和SpringMVC容器,很多剛接觸spring框架的同志都有點(diǎn)懵,甚至是一頭霧水,分不清楚兩者的關(guān)系和區(qū)別。這倆容器呢雖然有必然的聯(lián)系,但是他們的區(qū)別也是有的。下面我就簡(jiǎn)單描述下。

      一、前言

      首先在我們開發(fā)中會(huì)與到各種各樣的容器,今天我們就說一下spring 容器與springmvc容器。Spring和SpringMVC作為Bean管理容器和MVC層的默認(rèn)框架,已被眾多web應(yīng)用采用。但是在實(shí)際應(yīng)用中,初級(jí)開發(fā)者常常會(huì)因?qū)pring和SpringMVC的配置失當(dāng)導(dǎo)致一些奇怪的異常現(xiàn)象,比如Controller的方法無法攔截、Bean被多次加載等問題,這種情況發(fā)生的根本原因在于開發(fā)者對(duì)Spring容器和SpringMVC容器之間的關(guān)系了解不夠深入。

      在Spring整體框架的核心概念中,容器的核心思想是管理Bean的整個(gè)生命周期。但在一個(gè)項(xiàng)目中,Spring容器往往不止一個(gè),最常見的場(chǎng)景就是在一個(gè)項(xiàng)目中引入Spring和SpringMVC這兩個(gè)框架,其本質(zhì)就是兩個(gè)容器。首先 springmvc和spring它倆都是容器,容器就是管理對(duì)象的地方,例如Tomcat,就是管理servlet對(duì)象的,而springMVC容器和spring容器,就是管理bean對(duì)象的地方,再說的直白點(diǎn),springmvc就是管理controller對(duì)象的容器,spring就是管理service和dao的容器,這下你明白了吧。所以我們?cè)趕pringmvc的配置文件里配置的掃描路徑就是controller的路徑,而spring的配置文件里自然配的就是service和dao的路徑

      SpringMVC.xml文件所配置的路徑:

      applicationContext-service.xml文件所配置的路徑:

      其次, spring容器和springmvc容器的關(guān)系是父子容器的關(guān)系。spring容器是父容器,springmvc是子容器。在子容器里可以訪問父容器里的對(duì)象,但是在父容器里不可以訪問子容器的對(duì)象,說的通俗點(diǎn)就是,在controller里可以訪問service對(duì)象,但是在service里不可以訪問controller對(duì)象  所以這么看的話,所有的bean,都是被spring或者springmvc容器管理的,他們可以直接注入。然后springMVC的攔截器也是springmvc容器管理的,所以在springmvc的攔截器里,可以直接注入bean對(duì)象。

      二、Spring容器、SpringMVC容器與ServletContext之間的關(guān)系

      在Web容器中配置Spring時(shí),你可能已經(jīng)司空見慣于web.xml文件中的以下配置代碼,下面我們以該代碼片段為基礎(chǔ)來了解Spring容器、SpringMVC容器與ServletContext之間的關(guān)系。要想理解這三者的關(guān)系,需要先熟悉Spring是怎樣在web容器中啟動(dòng)起來的。Spring的啟動(dòng)過程其實(shí)就是其Spring IOC容器的啟動(dòng)過程。特別地,對(duì)于web程序而言,IOC容器啟動(dòng)過程即是建立上下文的過程。

      …org.springframework.web.context.ContextLoaderListenercontextConfigLocationclasspath:applicationContext.xmlSpringMVCorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath:springmvc.xml1SpringMVC/ …

      Spring的啟動(dòng)過程

    1. 對(duì)于一個(gè)web應(yīng)用,其部署在web容器中,web容器提供其一個(gè)全局的上下文環(huán)境,這個(gè)上下文就是ServletContext,其為后面的spring IoC容器提供宿主環(huán)境;
    2. 在web.xml中會(huì)提供有contextLoaderListener。在web容器啟動(dòng)時(shí),會(huì)觸發(fā)容器初始化事件,此時(shí)contextLoaderListener會(huì)監(jiān)聽到這個(gè)事件,其contextInitialized方法會(huì)被調(diào)用。在這個(gè)方法中,spring會(huì)初始化一個(gè)啟動(dòng)上下文,這個(gè)上下文被稱為根上下文,即WebApplicationContext。WebApplicationContext是一個(gè)接口類,確切的說,其實(shí)際的實(shí)現(xiàn)類是XmlWebApplicationContext,它就是spring的IoC容器,其對(duì)應(yīng)的Bean定義的配置由web.xml中的標(biāo)簽指定。在這個(gè)IoC容器初始化完畢后,Spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE為屬性Key,將其存儲(chǔ)到ServletContext中,便于獲??;
    3. ContextLoaderListener監(jiān)聽器初始化完畢后,開始初始化web.xml中配置的Servlet,這個(gè)servlet可以配置多個(gè),以最常見的DispatcherServlet為例,這個(gè)servlet實(shí)際上是一個(gè)標(biāo)準(zhǔn)的前端控制器,用以轉(zhuǎn)發(fā)、匹配、處理每個(gè)servlet請(qǐng)求。DispatcherServlet上下文在初始化的時(shí)候會(huì)建立自己的IoC上下文,用以持有spring mvc相關(guān)的bean。特別地,在建立DispatcherServlet自己的IoC上下文前,會(huì)利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先從ServletContext中獲取之前的根上下文(即WebApplicationContext)作為自己上下文的parent上下文。有了這個(gè)parent上下文之后,再初始化自己持有的上下文。這個(gè)DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到,大概的工作就是初始化處理器映射、視圖解析等。這個(gè)servlet自己持有的上下文默認(rèn)實(shí)現(xiàn)類也是mlWebApplicationContext。初始化完畢后,spring以與servlet的名字相關(guān)(此處不是簡(jiǎn)單的以servlet名為Key,而是通過一些轉(zhuǎn)換,具體可自行查看源碼)的屬性為屬性Key,也將其存到ServletContext中,以便后續(xù)使用。這樣每個(gè)servlet就持有自己的上下文,即擁有自己獨(dú)立的bean空間,同時(shí)各個(gè)servlet共享相同的bean,即根上下文(第2步中初始化的上下文)定義的那些bean。
    4. Spring容器與SpringMVC的容器聯(lián)系與區(qū)別

      ContextLoaderListener中創(chuàng)建Spring容器主要用于整個(gè)Web應(yīng)用程序需要共享的一些組件,比如DAO、數(shù)據(jù)庫的ConnectionFactory等;而由DispatcherServlet創(chuàng)建的SpringMVC的容器主要用于和該Servlet相關(guān)的一些組件,比如Controller、ViewResovler等。它們之間的關(guān)系如下:

      作用范圍

      子容器(SpringMVC容器)可以訪問父容器(Spring容器)的Bean,父容器(Spring容器)不能訪問子容器(SpringMVC容器)的Bean。也就是說,當(dāng)在SpringMVC容器中g(shù)etBean時(shí),如果在自己的容器中找不到對(duì)應(yīng)的bean,則會(huì)去父容器中去找,這也解釋了為什么由SpringMVC容器創(chuàng)建的Controller可以獲取到Spring容器創(chuàng)建的Service組件的原因。

      具體實(shí)現(xiàn)

      在Spring的具體實(shí)現(xiàn)上,子容器和父容器都是通過ServletContext的setAttribute方法放到ServletContext中的。但是,ContextLoaderListener會(huì)先于DispatcherServlet創(chuàng)建ApplicationContext,DispatcherServlet在創(chuàng)建ApplicationContext時(shí)會(huì)先找到由ContextLoaderListener所創(chuàng)建的ApplicationContext,再將后者的ApplicationContext作為參數(shù)傳給DispatcherServlet的ApplicationContext的setParent()方法。也就是說,子容器的創(chuàng)建依賴于父容器的創(chuàng)建,父容器先于子容器創(chuàng)建。在Spring源代碼中,你可以在FrameServlet.java中找到如下代碼:

      wac.setParent(parent);

      其中,wac即為由DisptcherServlet創(chuàng)建的ApplicationContext,而parent則為有ContextLoaderListener創(chuàng)建的ApplicationContext。此后,框架又會(huì)調(diào)用ServletContext的setAttribute()方法將wac加入到ServletContext中。

      三、Spring容器和SpringMVC容器的配置

      在Spring整體框架的核心概念中,容器是核心思想,就是用來管理Bean的整個(gè)生命周期的,而在一個(gè)項(xiàng)目中,容器不一定只有一個(gè),Spring中可以包括多個(gè)容器,而且容器間有上下層關(guān)系,目前最常見的一種場(chǎng)景就是在一個(gè)項(xiàng)目中引入Spring和SpringMVC這兩個(gè)框架,其實(shí)就是兩個(gè)容器:Spring是根容器,SpringMVC是其子容器。在上文中,我們提到,SpringMVC容器可以訪問Spring容器中的Bean,Spring容器不能訪問SpringMVC容器的Bean。但是,若開發(fā)者對(duì)Spring容器和SpringMVC容器之間的關(guān)系了解不夠深入,常常會(huì)因配置失當(dāng)而導(dǎo)致同時(shí)配置Spring和SpringMVC時(shí)出現(xiàn)一些奇怪的異常,比如Controller的方法無法攔截、Bean被多次加載等問題。

      在實(shí)際工程中,一個(gè)項(xiàng)目中會(huì)包括很多配置,根據(jù)不同的業(yè)務(wù)模塊來劃分,我們一般思路是各負(fù)其責(zé),明確邊界,即:Spring根容器負(fù)責(zé)所有其他非controller的Bean的注冊(cè),而SpringMVC只負(fù)責(zé)controller相關(guān)的Bean的注冊(cè),下面我們演示這種配置方案。

      (1). Spring容器配置

      Spring根容器負(fù)責(zé)所有其他非controller的Bean的注冊(cè):

      (2). SpringMVC容器配置

      SpringMVC只負(fù)責(zé)controller相關(guān)的Bean的注冊(cè),其中@ControllerAdvice用于對(duì)控制器進(jìn)行增強(qiáng),常用于實(shí)現(xiàn)全局的異常處理類:

      在中可以添加use-default-filters,Spring配置中的use-default-filters用來指示是否自動(dòng)掃描帶有@Component、@Repository、@Service和@Controller的類。默認(rèn)為true,即默認(rèn)掃描。如果想要過濾其中這四個(gè)注解中的一個(gè),比如@Repository,可以添加子標(biāo)簽,如下:

      而子標(biāo)簽是用來添加掃描注解的:

      四、Spring容器和SpringMVC容器的配置失當(dāng)帶來的問題

      問題描述

      在一個(gè)項(xiàng)目中,想使用Spring AOP在Controller中切入一些邏輯,但發(fā)現(xiàn)不能切入到Controller的中,但可以切入到Service中。最初的配置情形如下:

      1). Spring的配置文件application.xml包含了開啟AOP自動(dòng)代理、Service掃描配置以及Aspect的自動(dòng)掃描配置,如下所示:

      2). Spring MVC的配置文件spring-mvc.xml主要內(nèi)容是Controller層的自動(dòng)掃描配置。

      3). 增強(qiáng)代碼為如下:

      @Component@Aspectpublic class SecurityAspect {private static final String DEFAULT_TOKEN_NAME = “X-Token”;private TokenManager tokenManager;@Resource(name = “tokenManager”)public void setTokenManager(TokenManager tokenManager) {this.tokenManager = tokenManager;}@Around(“@annotation(org.springframework.web.bind.annotation.RequestMapping)”)public Object execute(ProceedingJoinPoint pjp) throws Throwable {// 從切點(diǎn)上獲取目標(biāo)方法MethodSignature methodSignature = (MethodSignature) pjp.getSignature();Method method = methodSignature.getMethod();// 若目標(biāo)方法忽略了安全性檢查,則直接調(diào)用目標(biāo)方法if (method.isAnnotationPresent(IgnoreSecurity.class)) {System.out.println(“method.isAnnotationPresent(IgnoreSecurity.class) : “+ method.isAnnotationPresent(IgnoreSecurity.class));return pjp.proceed();}// 從 request header 中獲取當(dāng)前 tokenString token = WebContext.getRequest().getHeader(DEFAULT_TOKEN_NAME);// 檢查 token 有效性if (!tokenManager.checkToken(token)) {String message = String.format(“token [%s] is invalid”, token);throw new TokenException(message);}// 調(diào)用目標(biāo)方法return pjp.proceed();}}

      4). 需要被代理的Controller如下:

      @RestController@RequestMapping(“/tokens”)public class TokenController {private UserService userService;private TokenManager tokenManager;public UserService getUserService() {return userService;}@Resource(name = “userService”)public void setUserService(UserService userService) {this.userService = userService;}public TokenManager getTokenManager() {return tokenManager;}@Resource(name = “tokenManager”)public void setTokenManager(TokenManager tokenManager) {this.tokenManager = tokenManager;}@RequestMapping(method = RequestMethod.POST)@IgnoreSecuritypublic Response login(@RequestParam(“uname”) String uname,@RequestParam(“passwd”) String passwd) {boolean flag = userService.login(uname, passwd);if (flag) {String token = tokenManager.createToken(uname);System.out.println(“**** Token **** : ” + token);return new Response().success(“Login Success…”);}return new Response().failure(“Login Failure…”);}@RequestMapping(method = RequestMethod.DELETE)@IgnoreSecuritypublic Response logout(@RequestParam(“uname”) String uname) {tokenManager.deleteToken(uname);return new Response().success(“Logout Success…”);}}

      在運(yùn)行過程中,發(fā)現(xiàn)這樣配置并沒有起作用,AOP配置不生效,沒有生成TokenController的代理。

      解決方案

      由上一節(jié)可知,原因有兩點(diǎn):

      • Spring容器與SpringMVC容器分別基于各自的配置文件進(jìn)行初始化,所以,在SpringMVC容器創(chuàng)建TokenController時(shí),由于其沒有啟用AOP代理,導(dǎo)致SpringMVC容器沒有為TokenController生成代理,所以沒有生效。
      • 雖然父容器啟用了AOP代理,但由于父子容器的獨(dú)立性,無濟(jì)于事。

      因此,我們只需要在SpringMVC的配置文件中添加Aspect的自動(dòng)掃描配置即可實(shí)現(xiàn)所要的效果。此外,一般地,SpringMVC容器只管理Controller,剩下的Service、Repository 和 Component 由Spring容器只管理,不建議兩個(gè)容器上在管理Bean上發(fā)生交叉。因此,建議配置為:

      SpringMVC 配置:

      Spring配置:

      總結(jié)

      springmvc容器是spring容器的子容器,但是子容器可以父容器的bean, 但是父容器不能訪問子容器的bean。Spring容器和SpringMVC容器雖然是父容器與子容器的關(guān)系,但二者之間具有一定的獨(dú)立性。具體來說,兩個(gè)容器基于各自的配置文件分別進(jìn)行初始化,只有在子容器找不到對(duì)應(yīng)的Bean時(shí),才回去父容器中去找并加載

      寫在最后

      希望通過這篇文章能讓大家分清楚spring容器和SpringMVC容器的關(guān)系與區(qū)別。雖然這些知識(shí)點(diǎn)都是老生常談,不否認(rèn)還是很多人分不清和不了解,但知識(shí)點(diǎn)不管是不是老生常談也都是需要掌握的,畢竟基礎(chǔ)要打好,這樣才能有更高的成就賺到更多的錢呀。好了本文到此結(jié)束了,希望能對(duì)鐵子們有幫助和收獲。喜歡的鐵子們可以點(diǎn)點(diǎn)贊和關(guān)注, 文章持續(xù)更新,也可以評(píng)論出你想看哪一塊技術(shù)。鐵子們的支持是我的動(dòng)力,創(chuàng)作離不開鐵子們的支持,在此先感謝大家!

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
      (0)
      用戶投稿
      上一篇 2022年9月17日 07:07
      下一篇 2022年9月17日 07:07

      相關(guān)推薦

      • 補(bǔ)齊短板夯實(shí)基礎(chǔ)-開源IM項(xiàng)目OpenIM關(guān)于初始化登錄好友接口介紹

        OpenIM文檔方面的建設(shè)一直遠(yuǎn)遠(yuǎn)落后于開發(fā), 也經(jīng)常被開發(fā)者詬病,在接下來一周的時(shí)間里,我們重點(diǎn)補(bǔ)齊文檔,讓開發(fā)者更輕松接入。由于app sdk底層都是go來實(shí)現(xiàn),所以本文先寫一…

        2022年6月27日
      • shell腳本自動(dòng)化更新rancher證書

        rancher每隔一年證書會(huì)到期,如何自動(dòng)化處理證書到期的問題呢? 手工處理步驟: cd ..Smartbi_All/rancher_data/management-state/t…

        2022年6月12日
      • 什么是微服務(wù)?

        微服務(wù)已經(jīng)成為現(xiàn)代軟件開發(fā)的新寵,盡管它們已有十多年的歷史。但是,盡管有好處,但這種范式很容易出錯(cuò)。那么讓我們來探討一下微服務(wù)是什么,更重要的是,它們不是什么。 什么是微服務(wù)? 微…

        2022年6月22日
      • Spring源碼之容器的功能擴(kuò)展和refresh方法解析

        容器的功能擴(kuò)展和refresh方法解析 在之前文章中我們了解了關(guān)于Spring中bean的加載流程,并一直使用BeanFactory接口以及它的默認(rèn)實(shí)現(xiàn)類XmlBeanFactor…

        2022年6月20日
      • 白色手機(jī)殼發(fā)黃怎么辦變白(透明手機(jī)殼發(fā)黃清洗小竅門)

        現(xiàn)在很多朋友都喜歡給手機(jī)套上一個(gè)手機(jī)殼,這樣不但能夠保護(hù)手機(jī),防止手機(jī)摔壞,而且還可以提高手機(jī)外表的美觀度。不過像這種透明的手機(jī)殼,時(shí)間用久了之后,就容易出現(xiàn)微微發(fā)黃的情況。 手機(jī)…

        2022年5月2日
      • Spring Boot面試題(總結(jié)最全面的面試題?。。。?

        什么是 Spring Boot? Spring Boot 是 Spring 開源組織下的子項(xiàng)目,是 Spring 組件一站式解決方案,主要是簡(jiǎn)化了使用 Spring 的難度,簡(jiǎn)省了…

        2022年6月27日
      • 云原生(十四) 容器

        深入萬物基礎(chǔ)-容器 一、思考 我們?cè)?k8s 里面的容器和 docker 的容器有什么異同? 其實(shí) docker 之前有自己的一套編排軟件:docker swarm 它可以在多臺(tái)主…

        2022年8月16日
      • 手性骨架單晶微管的同步組裝

        手性骨架單晶微管的同步組裝 文章出處:Osamu Oki, Hiroshi Yamagishi, Yasuhiro Morisaki, Ryo Inoue, Kana Ogawa,…

        2022年8月17日
      • ffmpeg播放器實(shí)現(xiàn)詳解 – 框架搭建

        ffplay是ffmpeg源碼中一個(gè)自帶的開源播放器實(shí)例,同時(shí)支持本地視頻文件的播放以及在線流媒體播放,功能非常強(qiáng)大。 FFplay: FFplay is a very simpl…

        2022年6月26日
      • 暗區(qū)突圍倉庫怎么擴(kuò)容 倉庫擴(kuò)容方法介紹

        暗區(qū)突圍倉庫的容量是有限的,玩家在儲(chǔ)藏物品的時(shí)候發(fā)現(xiàn)倉庫不夠用,那么大家可以選擇給倉庫擴(kuò)容,今天小編就來給大家分享一下倉庫擴(kuò)容的方法,詳細(xì)可以多參考下面的攻略,了解倉庫擴(kuò)容的更多技…

        2022年11月17日

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息