如何将生成的单件对象注入工厂

时间:2014-08-07 01:01:49

标签: java spring oop

即使在对工厂和依赖注入进行类似的问题之后,我也找不到答案。

我们说我有一个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。有没有更好的方法?

1 个答案:

答案 0 :(得分:2)

有很多方法可以做到这一点,但这里有两种方法。

在你的问题中你有这个:

public EventHandler eventHandlerA() { return new EventHandler(depA()); }

现在我不知道你是否打算这样做,但是你的bean在每次注入时都会是一个不同的实例,因为它会在每个返回语句中创建一个新实例。您基本上已将配置变为工厂。我将假设这是无意的。

方法1


我认为这是我将使用的策略,因为您可以添加一大堆处理程序,您不会污染您的应用程序上下文命名空间并且它干净且易于遵循。对于此方法,我将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;
    }
}

方法2

<小时/> 只需将@Component添加到所有事件处理程序,并确保它们位于组件扫描路径中。

@Component
public class EventHandlerA implements EventHandler