Spring Bean Factory使用类名

时间:2017-08-25 00:02:47

标签: java spring javabeans factory factory-pattern

我有一个类似的接口/实现:

public interface Processor {
    void processMessage(Message m);
}

@Component
public class FooAProcessor implements Processor {
    private FooA fooA;

    public FooAProcessor(FooA fooA) {
        this.fooA = fooA;
    }

    @Override
    public void processMessage(Message m) {
        //do stuff
    }
}

@Component
public class FooBProcessor implements Processor {
    private FooA fooA;

    public FooBProcessor(FooA fooA) {
        this.fooA = fooA;
    }

    @Override
    public void processMessage(Message m) {
        //do stuff
    }
}

FooA bean很简单,就像这样:

@Component
public class FooA {
    //stuff
}

消息类:

public class Message {
    private Class clazz;
}

我正在将消息从队列中拉出来。我需要提供一个具体的处理器来适当地处理不同类型的消息。这是消息接收者:

public class MessageReceiver {
    public void handleMessage(Message m) {
        Processor processor = //get concrete implementation from Message clazz
        processor.processMessage(m);
    }
}

我如何使用类名/对象来定义Processor的具体实现?

我的第一个想法是开发某种类型的工厂,并提供具体的实现。像这样:

@Component
public class ProcessorFactory {
    private FooAProcessor fooAProcessor;
    private FooBProcessor fooBProcessor;

    public ProcessorFactory(FooAProcessor fooAProcessor, FooBProcessor fooBProcessor) {
        this.fooAProcessor = fooAProcessor;
        this.fooBProcessor = fooBProcessor;
    }

    public Processor getFactory(Class clazz) {
        if(clazz.isAssignableFrom(FooAProcessor.class)) {
            return fooAProcessor;
        }
    }
}

或者像这样使用应用程序上下文:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getBean(clazz);

这是解决此问题的最佳方法吗?有更好的做法吗?

1 个答案:

答案 0 :(得分:0)

您可以将ApplicationContext注入工厂并从那里获取咖啡豆:

@Component
public class Factory {

    @Autowired ApplicationContext applicationContext;

    public Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }
}

或者您可以将处理器放入map并从中获取:

@Component
public class ProcessorFactory {

    private final Processor fooAProcessor;
    private final Processor fooBProcessor;
    private final Map<Class<T extends Processor>, Processor> beanMap;

    public ProcessorFactory (Processor fooAProcessor, Processor fooBProcessor) {
        this.fooAProcessor = fooAProcessor;
        this.fooBProcessor = fooBProcessor;
        this.beanMap = new HashMap(2);
    }

    @PostConstruct
    public void init() {
        beanMap.put(FooAProcessor.class, fooAProcessor);
        beanMap.put(FooBProcessor.class, fooBProcessor);
    }

    public Processor getProcessor(Class<T extends Processor> clazz) {
        return beanMap.get(clazz);
    }
}

我建议在使用spring上下文时不要依赖类,而是使用beanNames。