Как зарегистрировать POJO фабрику * методов * с компонентом Spring? - PullRequest
0 голосов
/ 26 марта 2020

У меня есть проблема с дизайном 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, и т. Д. c).

Теперь я хотел бы разместить 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);
    }

Это работает, сортировка из, но я не могу не чувствовать, что что-то упустил. Есть ли способ зарегистрировать методы загрузки как компоненты?

Примечания:

  • Я попытался обозначить классы POJO с помощью @Configuration, но тогда он обрабатывает класс как компонент. Но без этой или другой аннотации стереотипа любой @Bean в POJO не сканируется.
  • I может просто программно зарегистрировать каждый загрузчик POJO в менеджере, но это выглядит немного глупо при использовании DI framework.
  • Менеджер ищет загрузчик по name , поэтому мы ищем его из контекста, а не просто по автоматическому подключению.

I ' В течение многих лет мы разрабатывали с Spring, но, похоже, у них есть «мертвая зона» с этим дизайном (или его отсутствие!) Есть ли лучший подход?

Ответы [ 2 ]

0 голосов
/ 28 марта 2020

Похоже, что нет волшебного c решения для этого, если мы хотим разместить фабрику и код POJO в одном и том же исходном файле, в основном один имеет для создания отдельного @Component зарегистрировать фабрики POJO.

Это означает, что мы должны обернуть каждый метод фабрики в классе так, чтобы его можно было сканировать компонентом, а не (например) просто иметь константу класса stati c для выполнения это, что-то вроде этого:

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-компонента, и это именно то, что мне нужно для поиска фабрики по имени. Я назову это ничьей!

0 голосов
/ 26 марта 2020

Я не уверен, правильно ли я понимаю вашу проблему, что вы хотите, чтобы создать объекты, которыми будет управлять Spring? Вы смотрели на Spring BeanFactory ?

...