簡體   English   中英

如何使用 Spring 組件注冊 POJO factory *methods*?

[英]How to register POJO factory *methods* with a Spring component?

我有一個以前從未遇到過的 Spring 設計問題:

我有一個管理一堆 POJO 的應用程序,我想為每個 POJO 類注冊一個工廠,以便集中的 @Component 可以進行管理。 像這樣的東西:

class RouteLink implements Link {
}

class HiddenLink implements Link {
}

... lots of others

interface Loader {
    Link load(Element xml);
}

@Component
class Manager {
    private final Map<String, Loader> loaders = ...

    public void create(Element xml) {
        // Create link
        final String type = ... // from XML
        final Loader loader = loaders.get(type);
        final Link link = loader.load(xml);

        // Do something with the link we created
        ...
    }
}

(鏈接是從 XML 元素創建的,但這對問題並不重要 - 它可以來自文本或其他 POJO 等)。

現在我想共同定位 POJO 及其關聯的Loader 可以創建一個 @Configuration 類,該類為每種類型創建一個 @Bean,但這違反了協同定位並要求開發人員(我!)不斷在源文件之間切換。

理想情況下,我想做以下事情:

class RouteLink implements Link, Loader {
    ...

    // <--- some Spring magic here to register this as a factory
    public Link load(Element xml) {
        ...
    }
}

load()方法不能是 @Bean 或 @Component 因為我們正在處理 POJO。 所以我被迫創建一個新類只是為了調用一個方法:

class RouteLink ... {
    ...

    @Component
    public class RouteLinkLoader implements Loader {
        public Link load(Element xml) { .... }
    }
}

並且加載器像這樣在管理器中注冊:

    public Manager(ApplicationContext ctx) {
        loaders = ctx.getBeansOfType(Loader.class);
    }

它有效,有點,但我不禁覺得我錯過了一些東西。 有沒有辦法將加載方法注冊為組件?

筆記:

  • 我嘗試用 @Configuration 表示 POJO 類,但隨后將該類視為 bean。 但是如果沒有那個或另一個構造型注釋,POJO 中的任何 @Bean 都不會被掃描。
  • 可以以編程方式向管理器注冊每個 POJO 加載器,但是在使用 DI 框架時這似乎有點愚蠢。
  • 管理器按名稱查找加載器,這就是為什么我們從上下文而不是簡單地自動連接來查找它們的原因。

我多年來一直在使用 Spring 進行開發,但似乎對這種設計有一個盲點(或缺乏它!)有沒有更好的方法?

我不確定我是否正確理解您的問題,您想要的是創建將由 Spring 管理的對象嗎? 你看過 Spring BeanFactory嗎?

所以如果我們想將工廠和 POJO 代碼放在同一個源文件中,似乎沒有什么神奇的解決方案,基本上必須創建一個單獨的@Component來注冊 POJO 工廠。

這意味着我們必須將每個工廠方法包裝在一個類中,以便可以對其進行組件掃描,而不是(例如)僅使用靜態類常量來執行此操作,如下所示:

class PojoClass {
    @MagicAnnotationHere
    public static final Loader LOADER = xml -> new PojoClass(...);
}

做不到,所以工廠方法變成了一流的組件類,這意味着更多的代碼:

class PojoClass {
    ...
    @Component
    class PojoLoader implements Loader {
        @Override
        public void load(Element xml) { ... }
    }
}

從好的方面來說,工廠可以@AutoWired到管理器組件中,如下所示:

@Component
class Manager {
    @Autowired
    private final Map<String, Loader> loaders = new HashMap<>();

Spring 自動神奇地填充按 bean 名稱索引的映射,這正是我按名稱查找工廠所需的。 我稱之為平局!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM