即使在对工厂和依赖注入进行类似的问题之后,我也找不到答案。
我们说我有一个EventHandler
工厂,根据事件类型提供不同类型的EventHandler
。每种类型的EventHandler
都有自己的依赖关系用于处理该事件,这些可能与其他EventHandler
类型不同。
public interface EventHandler {
void handle(Event e);
}
public class EventHandlerA implements EventHandler{
private DependencyA depA;
//constructors for depA
}
public class EventHandlerB implements EventHandler{
private DependencyB depB;
//constructors for depB
}
public class Factory {
public EventHandler getHandler(EventType type) {
if(type.equals("A")) {
//return instance of EventHandlerA
}
}
}
@Configuration
public class Configuration {
@Bean
public EventHandler eventHandlerA() { return new EventHandler(depA()); }
@Bean
public Factory factory() { //.. ?? }
}
我的问题是 - 我正在使用带有Spring
注释的@Configuration
@Bean
来创建所有这些事件处理程序和工厂的单例bean。如何将各种事件处理程序的这些bean注入工厂,以便工厂可以根据事件类型返回这些实例。
我能想到的一种直接方法是在工厂实例化期间(通过构造函数)将所有事件处理程序传递给工厂,并维护类型到处理程序的映射,然后在该映射上执行get操作。这种方法的缺点是,每当我需要向工厂添加新的事件处理程序时,我都必须修改构造函数或添加新的setter。有没有更好的方法?
答案 0 :(得分:2)
有很多方法可以做到这一点,但这里有两种方法。
在你的问题中你有这个:
public EventHandler eventHandlerA() { return new EventHandler(depA()); }
现在我不知道你是否打算这样做,但是你的bean在每次注入时都会是一个不同的实例,因为它会在每个返回语句中创建一个新实例。您基本上已将配置变为工厂。我将假设这是无意的。
我认为这是我将使用的策略,因为您可以添加一大堆处理程序,您不会污染您的应用程序上下文命名空间并且它干净且易于遵循。对于此方法,我将EventHandlerFactory
重命名为EventHandlerRepository
,使其更适合其功能。
加载配置后,所有事件处理程序都会添加到工厂,然后您可以@Autowire
在应用程序周围的工厂调用repository.getHandler(/*Type*/)
。
通过简单地将EventHandlerRepository
重命名为EventHandlerFactory
,然后将Class<? extends EventHandler>
传递给getHandler
而不是实际实例,并在{{1}上创建新实例,可以使用相同的设计模式来创建真正的工厂}}
<强>的EventType:强>
public enum EventType {
A, B;
}
<强> EventHandlerRepository:强>
public class EventHandlerRepository {
private Map<EventType, EventHandler> handlers;
public EventHandlerRepository() {
handlers = new HashMap<EventType, EventHandler>();
}
void synchronized registerHandler(EventType type, EventHandler handler) {
handlers.put(type, handler);
}
public synchronized EventHandler getHandler(EventType type) {
return handlers.get(type);
}
}
<强>配置:强>
@Configuration
public class Configuration {
private EventHandlerRepository repository = new EventHandlerRepository();
public Config() {
// register all your event handlers here
factory.registerHandler(EventType.A, new EventHandlerA());
}
@Bean
public EventHandlerRepository getEventHandlerRepository() {
return repository;
}
}
<小时/> 只需将
@Component
添加到所有事件处理程序,并确保它们位于组件扫描路径中。
@Component
public class EventHandlerA implements EventHandler