在Spring

时间:2015-08-03 14:50:59

标签: java spring autowired

我的应用程序中实现了一种生产者 - 消费者模式。在一端,生产者推动实体从不同来源收到处理,另一方面,我有消费者将这些事件从队列中取出并处理它们。

生产者和消费者都是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吗?

2 个答案:

答案 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注释类一样。

但是,我没有看到使用包装类的任何问题,如图所示。实际上,使用包装器类可以让您更轻松地在实施过程中添加适应性。