我的应用程序中实现了一种生产者 - 消费者模式。在一端,生产者推动实体从不同来源收到处理,另一方面,我有消费者将这些事件从队列中取出并处理它们。
生产者和消费者都是spring bean并自动发现,并且都需要链接到此共享队列。我知道我可以在xml文件或Java配置中定义我的bean,并将此Queue作为参数传递给构造函数参数或通过setter,但有没有办法自动导入它。我想到的唯一想法是为这个队列创建一个包装器,然后注入这个包装器:
@Component
public class QueueWrapper {
private final BlockingQueue<MyObject> sharedQueue = new LinkedBlockingQueue<>();
public void put(MyObject toPut) {
sharedQueue.put(toPut);
}
public MyObject take() {
return sharedQueue.take();
}
}
@Component
public class Producer {
@Autowire
private QueueWrapper queue;
....
}
@Component
public class Consumer {
@Autowire
private QueueWrapper queue;
....
}
是否值得创建此包装器?我知道@Resource
注释,但我只使用它与列表,映射和集合,实际上不知道如何配置资源Java配置文件。 Spring文档页面列表的XML示例:
<util:list id="emails">
<value>pechorin@hero.org</value>
<value>raskolnikov@slums.org</value>
<value>stavrogin@gov.org</value>
<value>porfiry@gov.org</value>
</util:list>
然后是Java类:
@Component
public class SomeClass {
@Resource(name="emails")
private List<String> emails;
}
有没有办法在java配置中将队列创建为此类资源?或者有其他方法将共享队列注入不同的bean吗?
答案 0 :(得分:4)
Don Bottstein所建议的将会起作用,你必须像这样使用它。
@Configuration
public class QueueConfig {
@Bean
public BlockingQueue<MyObject> blockingQueue() {
return new LinkedBlockingQueue<>();
}
}
然后在类Producer和Consumer中做这样的事情:
@Component
public class Producer {
@Autowired
private QueueConfig queueConfig;
public void produceMyObject(MyObject myObject) {
queueConfig.blockingQueue.put(myObject);
}
}
答案 1 :(得分:1)
基本上,您将定义一个@Configuration
带注释的类来注册给定类型的bean。如,
@Configuration
public class AppConfig {
@Bean
public BlockingQueue<MyObject> sharedQueue() {
return new LinkedBlockingQueue<>();
}
}
bean名称默认为方法的名称(在本例中为sharedQueue
),或者您可以覆盖注释中的名称(@Bean(name="someName")
)。默认范围是单例,可以使用方法上的@Scope(...)
进行更改。
@Configuration
类,就像@Component
注释类一样。
但是,我没有看到使用包装类的任何问题,如图所示。实际上,使用包装器类可以让您更轻松地在实施过程中添加适应性。