成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

『SpringMVC』<context:include-filter>&<

darryrzhong / 946人閱讀

摘要:現(xiàn)在給定一個(gè)項(xiàng)目的包結(jié)構(gòu)在中有以下配置只掃描注解可以看出要把最后的包寫(xiě)上,不能包含子包,所以不能寫(xiě)成。

  大家好,我是豬弟,豬在我心中從來(lái)不是蠢的代名詞,而是懶的代名詞,本次準(zhǔn)備記錄一個(gè)在開(kāi)發(fā)測(cè)試過(guò)程中遇到的問(wèn)題,跟蹤了三天spring和第三方RPC組件的源碼,最終發(fā)現(xiàn)了問(wèn)題是因?yàn)榈谌浇M件沒(méi)有處理好而父子容器導(dǎo)致的,還有一個(gè)因素是spring注解掃描重疊。

Spring版本:4.3.13.RELEASE

JDK版本:1.7_u25 64位

SpringMVC的配置中為了防止Spring重復(fù)創(chuàng)建同一個(gè)類(lèi)的實(shí)例,一般會(huì)用到的兩個(gè)子標(biāo)簽&& 。

但它使用的時(shí)候表現(xiàn)的效果并不是和語(yǔ)義上的完全一致,現(xiàn)在來(lái)看一下其中的坑:

在很多配置中一般都會(huì)把spring-config.xmlspring-mvc.xml進(jìn)行分開(kāi)配置,這種配置可以他們保證各司其職,在web.xml的一般配置中spring-mvc.xml實(shí)例創(chuàng)建初始化是以DispatchServlet為入口,而spring-config.xml實(shí)例創(chuàng)建初始化是以ContextLoadListener為入口的,容器的加載順序: listener -> filter -> servlet ,所以spring容器先初始化,springmvc容器后初始化 。

    
    
        contextConfigLocation
        
            classpath:spring-config.xml
        
    
    
        org.springframework.web.context.ContextLoaderListener
    

    
    
        blog-spring-mvc
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            
                classpath:spring-mvc.xml
            
        
        1
    
    
        blog-spring-mvc
        /
    

如果在spring-mvc.xml中配置掃描的包和spring-config.xml中的發(fā)生重疊,那么會(huì)導(dǎo)致一個(gè)bean被創(chuàng)建兩次,而且在spring中是存在父子容器的,spring容器是父容器,springmvc是子容器,springmvc創(chuàng)建的實(shí)例放在子容器中,spring創(chuàng)建的實(shí)例放在父容器中。

其實(shí)這同一個(gè)類(lèi)的兩個(gè)實(shí)例是不同的,springmvc創(chuàng)建實(shí)例默認(rèn)對(duì)象不實(shí)現(xiàn)接口(大家都知道Controller是不用實(shí)現(xiàn)接口的),所以springmvc創(chuàng)建的實(shí)例是直接使用目標(biāo)類(lèi)的構(gòu)造器來(lái)實(shí)例化的,而不是代理對(duì)象,即使一個(gè)類(lèi)實(shí)現(xiàn)了接口,但如果該類(lèi)是由springmvc實(shí)例化,那么springmvc也會(huì)直接使用該類(lèi)的構(gòu)造器直接創(chuàng)建一個(gè)對(duì)象(怎么去證明呢,你可以寫(xiě)一個(gè)定時(shí)任務(wù),在定時(shí)任務(wù)中注入Controller的實(shí)例,然后debug查看實(shí)例對(duì)象的地址,如果是代理對(duì)象在地址上都會(huì)有一個(gè)$Proxy的標(biāo)記,否則就不是代理對(duì)象),所以在controller層使用AOP時(shí)多數(shù)采用的是CGLIB子類(lèi)代理。

Spring創(chuàng)建實(shí)例會(huì)判斷目標(biāo)類(lèi)是否實(shí)現(xiàn)了接口,如果沒(méi)實(shí)現(xiàn)接口那么就直接采用目標(biāo)類(lèi)構(gòu)造器創(chuàng)建,像一般的service和dao都會(huì)采用接口方式編程,對(duì)于接口方式編程的類(lèi),spring創(chuàng)建的實(shí)例都是代理對(duì)象(這一點(diǎn)可以用debug的方式查看controller類(lèi)中注入的service實(shí)例對(duì)象地址,他們都帶有一個(gè)$Proxy的標(biāo)記,很容易就能看出都是代理對(duì)象)。

那么為了防止重疊我們要把重疊的部分去掉,現(xiàn)在有下面的一個(gè)需求:

spring-mvc.xml中只對(duì)工程中所有用@Controller注解的類(lèi)進(jìn)行掃描創(chuàng)建實(shí)例。

spring-config.xml中要對(duì)工程中所有的非@Controller注解的類(lèi)進(jìn)行掃描創(chuàng)建實(shí)例。

現(xiàn)在給定一個(gè)項(xiàng)目的包結(jié)構(gòu):

xin.sun.blog.controlller

xin.sun.blog.service

(1)在spring-mvc.xml中有以下配置:



    

可以看出要把最后的包寫(xiě)上,不能包含子包,所以不能寫(xiě)成: base-package="xin.sun.blog" 。如果這樣寫(xiě),對(duì)于 include-filter 標(biāo)簽來(lái)講它會(huì)掃描基包下面所有spring注解的類(lèi),而不是僅僅掃描 @Controller 。這點(diǎn)需要非常的注意,這一般會(huì)導(dǎo)致一個(gè)常見(jiàn)的錯(cuò)誤,那就是事務(wù)不起作用,補(bǔ)救的方法是添加 use-default-filters="false"。

(2)在spring-config.xml中有如下配置:



    

可以看到,他是要掃描xin.sun.blog包和子包下的所有spring注解的類(lèi),但是不包含@Controller注解的類(lèi)。對(duì)于exculude-filter不存在包不精確導(dǎo)致都進(jìn)行掃描的問(wèn)題。

那么還有一個(gè)問(wèn)題:當(dāng)掃描的包不小心重疊了,導(dǎo)致類(lèi)在父子容器各實(shí)例化了一遍,在 @Autowire 的時(shí)候會(huì)注入哪個(gè)容器中的對(duì)象呢?看一個(gè)Controller類(lèi),代碼如下:

@Controller
public class MyController{

    @Autowired
    private IValidService validService;
    //其他代碼省略 
}

答案是:Spring為了保證注入類(lèi)的一致性,采用了雙親委托的機(jī)制,如果父容器中存在該類(lèi)的實(shí)例那么優(yōu)先使用父容器中的實(shí)例,如果父容器中沒(méi)有該實(shí)例才會(huì)用子容器中的實(shí)例

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68326.html

相關(guān)文章

  • Python代碼太臃腫怎么辦?下給給大家總結(jié)幾個(gè)小技巧

      小編寫(xiě)這篇文章的一個(gè)主要目的,主要是給大家介紹,關(guān)于如何處理代碼臃腫的事項(xiàng),但是如果要處理的話,還是比較的麻煩的,那么,遇到這種問(wèn)題的話,需要怎么去處理呢?下面就給大家詳細(xì)的解答下?! ∈裁词菃涡写a  你可以將單行代碼視為壓縮在一起的代碼塊,使其適合一行。它是只包含在一行中的簡(jiǎn)潔、有用的程序?! 槭裁次倚枰鼈儭 ∪绻悴⒉幌矚g寫(xiě)單行代碼,或者你只是好奇為什么我們必須知道這些,那么下面是一...

    89542767 評(píng)論0 收藏0
  • 如何利用Pandas查詢選取數(shù)據(jù)

      小編寫(xiě)這篇文章的主要目的,主要還是利用Pandas這門(mén)工具,去進(jìn)行編程等一系列的一些操作,比如可以用來(lái)進(jìn)行增刪查改等一系列的操作步驟。那么,怎么利用Pandas去查詢數(shù)據(jù)呢?下面就給大家詳細(xì)解答下?! ∫?,Pandas查詢數(shù)據(jù)的幾種方法  df[]按行列選取,這種情況一次只能選取行或者列  df.loc方法,根據(jù)行、列的標(biāo)簽值查詢  df.iloc方法,根據(jù)行、列的數(shù)字位置查詢,根據(jù)索引定位 ...

    89542767 評(píng)論0 收藏0
  • Python中雙下使用方法解析

      在Python這門(mén)語(yǔ)言中,有一些比較特殊的使用方法,主要用到的是雙下劃線開(kāi)始和結(jié)束,正是因?yàn)槿绱?,他還有一個(gè)比較接地氣的名字,叫做雙下方法,感興趣的話,可以詳細(xì)的為大家進(jìn)行解答一下?! ∏把浴 〈蠹以趯?xiě)Python代碼的時(shí)候有沒(méi)有這樣的疑問(wèn)。  為什么數(shù)學(xué)中的+號(hào),在字符串運(yùn)算中卻變成拼接功能,如'ab'+'cd'結(jié)果為abcd;而*號(hào)變成了重復(fù)功能,如'...

    89542767 評(píng)論0 收藏0
  • CSRF攻擊

    一、什么是CSRF攻擊我們常常聽(tīng)到這樣一句話:默認(rèn)的鏈接不要點(diǎn),那些年也聽(tīng)過(guò),郵箱中的垃圾鏈接不要點(diǎn)。 因?yàn)榭赡苁呛诳桶l(fā)起的CSRF攻擊,所以在點(diǎn)擊之前最好是確認(rèn)鏈接的安全性。CSRF(Cross-site requests forgery)中文名:跨站腳本偽造簡(jiǎn)單的理解就是,黑客盜用了你的身份,以你的名義向你訪問(wèn)的站點(diǎn)發(fā)送請(qǐng)求。這些請(qǐng)求操作可能是轉(zhuǎn)發(fā)郵件、獲取發(fā)送內(nèi)容,發(fā)起轉(zhuǎn)賬、獲取權(quán)限等。CS...

    社區(qū)管理員 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<