日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring-基于注解的配置[01定义Bean+扫描Bean]

發布時間:2025/3/21 javascript 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring-基于注解的配置[01定义Bean+扫描Bean] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  • 概述
  • 使用注解定義Bean
  • 掃描注解定義的Bean
    • 使用步驟
    • 掃描特定的類 resource-pattern
      • 實例
    • include-filter exclude-filter過濾子元素的使用
      • 支持多種類型的過濾表達式
      • 實例
    • use-default-filters屬性
      • 實例

概述

前幾篇博文中主要講述了基于XML的配置。

不管是XML還是注解,他們都是在表達Bean定義的載體,其實質都是為Spring容器提供Bean定義的信息,在表現形式上都是將XML定義的內容通過類注解進行描述。

基于注解的配置方式,在Spring2.0引入,Spring2.5完善,Spring4.0得到了進一步的增強。

我們知道,Spring容器成功啟動的三大要件分別是:

  • bean的定義信息
  • bean的實現類
  • Spring本身
  • 如果采用XML的配置,則Bean的定義信息和Bean的實現類本身是分離的。
    而如果采用基于注解的配置方式,則Bean的定義信息通過Bean實現類上標注的注解實現。


    使用注解定義Bean

    在另外一篇博客中:Spring-Spring MVC + Spring JDBC + Spring Transaction + Maven 構建web登錄模塊

    以案例來說明:

    // 通過Spring注解定義一個DAO(這里略微改動了下,使用@Component ,更合適的是@Repository,僅僅是為了演示) @Component public class UserDao {.......}

    使用@Component注解在UserDao類聲明處對類進行標注,它可以被Spring容器識別,Spring容器自動將POJO轉換為容器管理的Bean。

    它和下面的XML配置是等效的

    <bean id="userDao" class="com.xgj.dao.UserDao">

    使用注解的方式,默認生成的beanId為類名的首字母小寫,也可指定其id,如:@Service("xgjService")

    除了@Component注解外,Spring還提供了3個功能基本和@Component等效的注解,分別用于對DAO、Service和Web層的Controller進行注解

    • @Repository用于對DAO實現類進行標注
    • @Service用于對Service實現類進行標注
    • @Controller用于對Controller實現類進行注解

    之所以要在@Component之外提供3個特殊的注解,是為了讓標注類本身的用途清晰化,當然了完全可以用@Component替代這3個特殊的注解, 但是我們推薦使用特定的注解標注特定的Bean,這樣可以明確的了解Bean的真是身份


    掃描注解定義的Bean

    Spring提供了一個context命名空間,它提供了通過掃描類包以應用注解定義Bean的方式。

    如下方式:

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- (1)聲明Context命名空間以及Schema文件 (2)掃描類包以及應用注解定義的bean --><context:component-scan base-package="com.xgj.ioc.configuration"/></beans>

    使用步驟

  • 首先聲明context命名空間和schema文件

  • 然后通過context命名空間的component-scan的base-package屬性指定一個需要掃描的基類包,Spring容器會掃描這個基類包里的所有類,并從類的注解信息中獲取Bean的定義信息。


  • 掃描特定的類 resource-pattern

    假設我們希望掃描特定的類,而非基包下所有的類,怎么辦呢?

    Spring context命名空間提供了resouce-pattern屬性過濾出特定的類

    <!-- 通過resource-pattern使Spring加載特定的Bean --><context:component-scan base-package="com.xgj.ioc.configuration.resourcePattern"resource-pattern="scan/*.class"/>

    這里設置的基類包為com.xgj.ioc.configuration.resourcePattern,默認情況下resource-pattern屬性的值為 **./*.class,即基類包里所有的類。

    如果有設置為scan/*.class,則Spring僅會掃描基類包里scan子包中的類。

    實例

    通過配置文件指定Spring只加載 scan目錄下的類的注解,測試resource-pattern屬性。

    配置文件:

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- 通過resource-pattern使Spring加載特定的Bean --><context:component-scan base-package="com.xgj.ioc.configuration.resourcePattern"resource-pattern="scan/*.class"/></beans>

    scan目錄下的POJO

    package com.xgj.ioc.configuration.resourcePattern.scan;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;@Component public class Pilot {@Autowiredprivate Plane plane;public void drivePlane() {plane.fly();} } package com.xgj.ioc.configuration.resourcePattern.scan;import org.springframework.stereotype.Component;@Component public class Plane {private String brand;private String color;private int speed;public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}public void introduce() {System.out.println("Plane information【 brand:" + brand + ",color:"+ color + ",speed:" + speed);}public void fly() {System.out.println("Plane begins to fly");} }

    測試類:

    package com.xgj.ioc.configuration.resourcePattern.scan;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class ConfigBeanTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/ioc/configuration/resourcePattern/resourcePatternBeans.xml");Pilot pilot = ctx.getBean("pilot", Pilot.class);pilot.drivePlane();Plane plane = ctx.getBean("plane", Plane.class);plane.setBrand("A380");plane.setColor("White");plane.setSpeed(800);plane.introduce();} }

    NoScan包下的POJO (PilotNoScan、PlaneNoScan)僅僅類名不同(同名的話,默認ID相同,Spring加載會報錯。)

    測試類

    package com.xgj.ioc.configuration.resourcePattern.noScan;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class ConfigBeanTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/ioc/configuration/resourcePattern/resourcePatternBeans.xml");PilotNoScan pilot = ctx.getBean("pilotNoScan", PilotNoScan.class);pilot.drivePlane();PlaneNoScan plane = ctx.getBean("planeNoScan", PlaneNoScan.class);plane.setBrand("A380-NoScan");plane.setColor("White-NoScan");plane.setSpeed(800);plane.introduce();} }

    運行scan報下的測試類

    運行noScan報下的測試類,報錯

    No bean named 'pilotNoScan' available

    說明,Spring容器并沒有實例化這個類。resource-pattern起了作用。

    當我們去掉配置文件中的 resource-pattern="scan/*.class"后,再此運行

    可見,Spring容器可以正確加載并實例化Bean


    include-filter exclude-filter過濾子元素的使用

    通過resource-pattern屬性可以按照資源名稱對基類包中的類進行過濾,如果我們有個需求:僅需過濾基類包中實現了XxxService接口的類或者標注了某個特定注解的類等 ,該怎么辦呢?

    Spring的<context:componet-scan>為我們提供了過濾子元素,我們可以輕松的通過其實現上面的需求。

    <context:component-scan base-package="com.xgj.ioc.configuration.resourcePattern"resource-pattern="scan/*.class"><context:include-filter type="regex" expression="com\.xgj\.ioc\.configuration\.resourcePattern\.scan.*"/> <context:exclude-filter type="aspectj" expression="com.xgj.ioc.configuration.resourcePattern..*Controller+"/> </context:component-scan>
    • <context:include-filter>表示要包含的目標類
    • <context:exclude-filter>表示要排除的目標類
    • 一個<context:component-scan>下可以有多個<context:include-filter>和<context:exclude-filter>元素

    支持多種類型的過濾表達式

    類別示例說明
    annotationcom.xgj.XxxAnnotation所有標注了XxxAnnotation的類。該類型采用目標類是否標志了某個注解進行過濾
    assignablecom.xgj.XxService所有繼承或擴展XXXService的類。該類型采用目標類是否繼承或者擴展了某個特定類進行過濾
    aspectjcom.xgj..*Service+所有類名以Service結束的類及繼承或者擴展他們的類。該類型采用AspectJ表達式進行過濾
    regexcom.xgj.auto..*所有com.xgj.auto類包下的類。該類型采用正則表達式根據目標類的類名進行過濾
    customcom.xgj.XxxTypeFilter采用XxxTypeFilter代碼方式實現過濾規則,該類必須實現org.springframework.core.type.TypeFilter接口

    在所有的過濾類型中,除了custom類型外,aspectj的過濾表達能力是最強的,可以輕易實現其他類型所能表達的過濾規則。

    實例

    我們先將測試類改下名,保證不重名,否則會拋出如下異常

    Annotation-specified bean name 'configBeanTest' for bean class [com.xgj.ioc.configuration.resourcePattern.scan.ConfigBeanTest] conflicts with existing, non-compatible bean definition of same name and class [com.xgj.ioc.configuration.resourcePattern.noScan.ConfigBeanTest]

    配置文件:

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- 通過resource-pattern使Spring加載特定的Bean <context:component-scan base-package="com.xgj.ioc.configuration.resourcePattern" resource-pattern="scan/*.class"/> --><!-- context:include-filter context:exclude-filter --><context:component-scan base-package="com.xgj.ioc.configuration.resourcePattern"><context:include-filter type="regex"expression="com\.xgj\.ioc\.configuration\.resourcePattern.*" /><context:exclude-filter type="aspectj" expression="com.xgj.ioc.configuration.resourcePattern..*NoScan+"/></context:component-scan></beans>

    配置文件解析:

    <context:include-filter type="regex"expression="com\.xgj\.ioc\.configuration\.resourcePattern.*" />

    使用<context:include-filter> ,通過regex正則表達式過濾方式,包含com.xgj.configuration.resourcePattern目錄下的所有類,按照項目結果包括scan和noScan子包中的注解類。

    <context:exclude-filter type="aspectj" expression="com.xgj.ioc.configuration.resourcePattern..*NoScan+"/>

    使用<context:exclude-filter>,通過aspectj的過濾方式,排除掉com.xgj.ioc.configuration.resourcePattern包及子包下所有以NoScan+結尾的類,按照項目結構即排除掉noScan子包下的注解類。


    其余POJO和測試類同上。

    測試scan包下的測試類

    測試noScan包下的測試類

    org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'pilotNoScan' available

    可見 <context:include-filter> 和 <context:exclude-filter>標簽起了作用。


    use-default-filters屬性

    use-default-filters屬性默認值為true,表示會對標注@Component、@Controller、@Service、@Reposity的Bean進行掃描。

    <context:component-scan>首先根據 exclude-filter列出需要排除的黑名單,然后再根據include-filter流出需要包含的白名單。 但是由于use-default-filters屬性默認值的作用,看下下面的配置片段,不但會對@Controller的bean進行掃描,還會會對@Component、@Service、@Reposity的Bean進行掃描。

    <context:component-scan base-package="com.xgj.ioc.configuration.resourcePattern"><context:include-filter type="annotation"expression="org.springframework.stereotype.Controller" /></context:component-scan>

    換句話講,上面的配置和不加<context:include-filter>的效果是一樣的,如果僅僅想掃描@Controller的bean,必須將use-default-filters屬性設置為false.

    如下所示

    <context:component-scan base-package="com.xgj.ioc.configuration.resourcePattern" use-default-filters="false"><context:include-filter type="annotation"expression="org.springframework.stereotype.Controller" /> </context:component-scan>

    實例

    配置文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.xgj.ioc.configuration.resourcePattern" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan></beans>

    運行測試類 com.xgj.ioc.configuration.resourcePattern.scan.ConfigBeanTest

    org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'pilot' available

    如果我們去掉use-default-filters=”false”試下呢?

    由此可見 use-default-filters=”false” 起到了只加載或者排除特定注解的功能。

    總結

    以上是生活随笔為你收集整理的Spring-基于注解的配置[01定义Bean+扫描Bean]的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。