Spring Bean Factory 使用类名

问题描述 投票:0回答:1

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

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

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

java spring javabeans factory factory-pattern
1个回答
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 。

© www.soinside.com 2019 - 2024. All rights reserved.