首頁 > 軟體

SpringMVC bean實現載入控制方法詳解

2022-08-30 14:03:49

1、Spring設定類排除載入SpringMVC的bean

SpringMVC 通常只需要載入 controller 包內的 bean,而 Spring 需要載入 dao 和 service 包內的 bean,為了省事,Spring 設定類經常設定掃描的包為一個大範圍的包(包含 dao 和 service 在內的包),此時 Spring 會錯誤或者多餘地載入到 controller 包內的 bean

使 Spring 排除載入 SpringMVC 的 bean 一般有兩種方法

  • 方法 1:掃描包時精確掃描需要的包,而不用大範圍的掃描
  • 方法 2:大範圍掃描,但是將不需要的 bean 過濾掉

方法 1 範例:

@Configuration
// 使 Spring 只掃描 dao 與 service 包
@ComponentScan({"com.mzz.dao", "com.mzz.service"})
public class SpringConfig {
}

方法 2:在 @ComponentScan 註解中可以設定 excludeFilters 屬性排除掉 不需要的 bean,excludeFilters 屬性的值是一個 Filter 註解,這個註解也在 ComponentScan 內,需要設定 type(過濾型別) 和 classes

下面的範例表示 Spring 的掃描範圍為 com.mzz 但是按註解型別過濾掉所有註解了 @Controller 的 bean

@Configuration
@ComponentScan(value = "com.mzz",
    excludeFilters = @ComponentScan.Filter(
            type = FilterType.ANNOTATION,   // 按照 註解 來進行過濾
            classes = {Controller.class}    // 過濾所有註解了 @Controller 的 bean
    )
)
public class SpringConfig {
}

由於 Filter 註解中 type 的預設值就是 FilterType.ANNOTATION,所以上面的程式碼可以簡寫成這樣:

@Configuration
@ComponentScan(value = "com.mzz",
    excludeFilters = @ComponentScan.Filter({Controller.class})
)
public class SpringConfig {
}

[補充]

當 Spring 和 SpringMVC 的設定類同時存在時,上述的方法二可能不會生效,原因是 Spring 進行大範圍掃描時可以掃描到 SpringMVC 的設定類,於是 SpringMVC 中的 bean 也被載入到 Spring 中

此時也有兩種解決方法

一是將 SpringMVC 的設定類移動到 Spring 掃描不到的包下(比如 com 包下)

二是 Spring 過濾時也將 SpringMVC 的設定類過濾掉,SpringMVC 的設定類會註解 @Configuration 和 @ComponentScan,可以對其進行過濾

@Configuration
@ComponentScan(value = "com.mzz",
        excludeFilters = @ComponentScan.Filter({Controller.class, ComponentScan.class})
)
public class SpringConfig {
}

2、Servlet容器設定類簡潔開發

public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer {
    // 載入 springMVC 容器設定
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    // 載入 spring 容器設定
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }
}

上面的類繼承自 AbstractDispatcherServletInitializer 抽象類,改為繼承 AbstractAnnotationConfigDispatcherServletInitializer 抽象類。則只需將設定類 class 返回即可,而不需要手動建立 Context,如下

public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }
    // 載入 springMVC 容器設定
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

視訊連結:傳送門

到此這篇關於SpringMVC bean實現載入控制方法詳解的文章就介紹到這了,更多相關SpringMVC bean載入控制內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com