Spring如何過濾掉不需要注入的物件
在Spring中經常會碰到這樣的問題,在service中經常需要注入第三方的配置資訊,如:搜尋引擎,訊息佇列等....但是由於service作為各個C端的中間的橋接層,所以需要在沒額C端都配置上對應的配置檔案或者實體宣告,可能在這些C端中,根本就沒有用到相關的功能!...如何能優雅的去除掉不需要的依賴?
本人總結了一下兩個方法,不足的地方還忘大家指點:
1:將第三方依賴項單獨做成一個service-jar包,在需要的專案中進行引用即可,但是前提,本身的專案結構的依賴,解耦有較好的規劃
2:在不需要用到該功能的C端,進行注入物件的過濾.
這裡就第二點進行簡單的描述:
因spring中物件的注入,我們一般使用的是ioc的方式,使用註解@Autowired註解需要注入的物件,但是再某些C端,可能根本沒用帶改物件,也就自然沒有該物件的注入,這時候,啟動專案,你會發現報錯,找不到該注入物件.spring報錯資訊還是挺準確的.對,我們受限想到的就是忽略該物件,檢視@Autowired,原始碼如下:
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { /** * Declares whether the annotated dependency is required. * <p>Defaults to {@code true}. */ boolean required() default true; }
required,是否必須.我們設為false,即可,如下:
@Autowired(required=false)
private MQConfig config; //引用統一的引數配置類
這是直接忽略掉該注入物件,還有種情況,我們需要忽略掉掉整個實現類中的物件注入這麼辦呢?或者忽略掉整個類的宣告這麼辦呢?
spring-context提供了多種支援
摘自其他網站的介紹:
context:component-scan節點允許有兩個子節點<context:include-filter>和<context:exclude-filter>。filter標籤的type和表示式說明如下:
Filter Type | Examples Expression | Description |
annotation | org.example.SomeAnnotation | 符合SomeAnnoation的target class |
assignable | org.example.SomeClass | 指定class或interface的全名 |
aspectj | org.example..*Service+ | AspectJ語法 |
regex | org\.example\.Default.* | Regelar Expression |
custom | org.example.MyTypeFilter | Spring3新增自訂Type,實作org.springframework.core.type.TypeFilter |
在我們的示例中,將filter的type設定成了正則表示式,regex,注意在正則裡面.表示所有字元,而\.才表示真正的.字元。我們的正則表示以Dao或者Service結束的類。
本人專案中的一個簡單配置例項spring-context.xml如下:
<context:component-scan base-package="com.xyy">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
<context:exclude-filter type="aspectj" expression="com.xyy.driver..*"/>
<context:exclude-filter type="aspectj" expression="com.xyy.erp..*"/>
<context:exclude-filter type="assignable" expression="com.xyy.common.config.ESMQConfig"/>
<context:exclude-filter type="assignable" expression="com.xyy.common.config.MQConfig"/>
</context:component-scan>
因為上面非必需注入物件
MQConfig種還包含了其他屬性的注入,所以這裡直接再spring的包掃描中忽略該物件的宣告...