2017-02-10 3 views
0

Я не могу найти изящный способ сделать это весной - представьте, у меня есть класс, который прослушивает сообщения:Разводка Несколько Фасоли Слушатель Стиля С весной

@Component 
public class MessageReceiver { 
    private List<MessageHandler> handlers = new ArrayList<>(); 

    public void receiveMessage(Message m) { 
    for(MessageHandler handler: handlers) { 
     handler.process(m); 
    } 
    } 

    public void registerMessageHandler(MessageHandler handler) { 
    handlers.add(handler); 
    } 
} 

В принципе, я хочу быть способный определять несколько фасолей MessageHandler и самостоятельно регистрироваться с помощью MessageReceiver. Я бы предпочел не поддерживать список MessageHandler где-то - мне просто хотелось бы, чтобы Spring обнаружила какие-либо в контексте (возможно, аннотированные @Bean или @Component) и попросите их вызвать метод registerMessageHandler() как часть процесса проводки.

Что было бы самым простым способом сделать это?

ответ

0

Считаете ли вы, что механизм публикации событий уже включен в Spring?

ApplicationEventPublisher может быть @Autowired и Spring соединит любой @Component, который реализует ApplicationListener<T> или метод с аннотацией @EventListener, если вы используете Spring 4.2 или более поздней версии.

Эта функция используется различными компонентами Spring, такими как Spring security для трансляции событий, например, когда пользователи аутентифицируются.

Вы можете прочитать об этом here

Edit Если вы не хотите использовать встроенный механизм сообщений вы можете просто построить свой собственный, используя тот же принцип автоматического обнаружения.

Текущая версия Spring позволяет @AutoWire список бобов в зависимости от типа, если все ваши MessageHandler экземпляры бобов, то это будет выглядеть следующим образом

@Component 
public class MessageReceiver { 
    private final List<MessageHandler> handlers; 

    @Autowired 
    public MessageReceiver(List<MessageHandler> handlers) { 
     this.handlers = handlers; 
    } 

    public void receiveMessage(Message m) { 
     for (MessageHandler handler : handlers) { 
      handler.process(m); 
     } 
    } 

} 

Если вы используете версию Spring, что не поддерживает сборку autowiring, тогда вы должны реализовать ApplicationContextAware, чтобы получить ссылку на ApplicationContext, поэтому вы можете позвонить getBeansOfType(), чтобы получить все MessageHandlers.

+0

Я думаю, это может быть сделано для работы, но это немного взломать и злоупотреблять механизмом событий для чего-то, чего он не должен был делать. Я думаю, что я предпочел бы поддерживать список обработчиков в компоненте '@ Configuration', что, по крайней мере, правильно, если немного дополнительной работы. – BarrySW19

+0

Если ваши обработчики заранее знают, как это звучит, они должны быть одноэлементными, что означает, что вы можете получить их из контекста Spring. Либо, имея «MessageReceiver» ApplicationContextAware', и затем посмотрите, используя 'getBeansOfType', или' @ Autowiring' 'List ' в 'MessageReceiver'. Если обработчики являются эфемерными, вам, вероятно, необходимо зарегистрировать/удалить их в коде. –

+0

Ах, я не видел коллекцию с автоподготовкой - это похоже на то, чего я хочу. – BarrySW19

Смежные вопросы