java 使用类名的Spring Bean Factory

vuktfyat  于 2024-01-05  发布在  Java
关注(0)|答案(1)|浏览(178)

我有一个这样的接口/实现:

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);


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

hfwmuf9z

hfwmuf9z1#

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

@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上下文时不要依赖class,而是使用beanNames。

相关问题