Spring使用@Autowired不能注入BlockingQueue的有关问题

Spring使用@Autowired不能注入BlockingQueue的问题

 

今天遇到一个问题,使用spring4配置BlockingQueue,在Java代码里面使用@Autowired注释方式注入该BlockingQueue,一直报错。

我的代码如下:

    @Autowired
    private BlockingQueue<CoreTask> alarmInnerQueue;

 

我的XML如下:

<bean id="alarmInnerQueue" class="org.kanpiaoxue.test.concurrent.UniqueLinkedBlockingQueue"/>

 说明一下,UniqueLinkedBlockingQueue 这个类是BlockingQueue的一个实现,我自己写的。

报错如下:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.concurrent.BlockingQueue com.baidu.rigel.dmap.sf.service.impl.AlarmFailureServiceImplTest.alarmInnerQueue; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.util.HashMap$Values' to required type 'java.util.concurrent.BlockingQueue'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.util.HashMap$Values] to required type [java.util.concurrent.BlockingQueue]: no matching editors or conversion strategy found
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
	... 26 more
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.util.HashMap$Values' to required type 'java.util.concurrent.BlockingQueue'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.util.HashMap$Values] to required type [java.util.concurrent.BlockingQueue]: no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:74)
	at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:40)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1014)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
	... 28 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.util.HashMap$Values] to required type [java.util.concurrent.BlockingQueue]: no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:287)
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:107)
	at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:64)
	... 32 more

 最后在spring的网站发现这是一个Bug,到现在还没有修复。而是采用了配置

javax.annotation.Resource的方式来绕过这个BUG。

正确的代码如下:

    @Resource(name="alarmInnerQueue")
    private BlockingQueue<CoreTask> alarmInnerQueue;

 

 

网站地址:https://jira.spring.io/browse/SPR-7798

http://forum.spring.io/forum/spring-projects/container/64548-problem-injecting-blockingqueue-by-applicationcontext-xml

内容:

Details

  • Type:Spring使用@Autowired不能注入BlockingQueue的有关问题 Bug
  • Status:RESOLVED
  • Priority:Spring使用@Autowired不能注入BlockingQueue的有关问题 Minor
  • Resolution:Duplicate
  • Affects Version/s:3.0.5
  • Fix Version/s:None
  • Component/s:Core:AOP
  • Labels:
    None
  • Reference URL:
    http://forum.springsource.org/showthread.php?t=72474
  • Last commented by a User:
    true

Description

Cannot @Autowire to inject an instance of java.util.concurrent.BlockingQueue. The above forum has a post from 2009. I was able to reproduce this problem and have attached a minimal example. This works with XML based bean configuration but not with the annotation @Autowired.

AppComponent.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example;
 
import java.util.concurrent.BlockingQueue;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
 
@Component
public class AppComponent {
 
    @Autowired
    public BlockingQueue queue;
 
    public static void main(String[] args) {
 
        new ClassPathXmlApplicationContext("com/example/context.xml").getBean(AppComponent.class);
    }
}

Config.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.example;
 
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class Config {
 
    @Bean
    public BlockingQueue blockingQueue() {
        return new LinkedBlockingQueue();
    }
}

context.xml:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
">
    <context:component-scan base-package="com.example" />
</beans>

The runtime error is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appComponent': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public java.util.concurrent.BlockingQueue com.example.AppComponent.queue; nested exception is org.springframework.beans.FatalBeanException: No element type declared for collection [java.util.concurrent.BlockingQueue]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.example.AppComponent.main(AppComponent.java:17)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: public java.util.concurrent.BlockingQueue com.example.AppComponent.queue; nested exception is org.springframework.beans.FatalBeanException: No element type declared for collection [java.util.concurrent.BlockingQueue]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
    ... 13 more
Caused by: org.springframework.beans.FatalBeanException: No element type declared for collection [java.util.concurrent.BlockingQueue]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:740)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
    ... 15 more

Attachments

Issue Links

is superseded by

Activity

 
  • All
  • Comments
  • Work Log
  • History
  • Activity
  • Transitions
 
Spring使用@Autowired不能注入BlockingQueue的有关问题Michael F added a comment - 05/Jul/11 7:13 AM

(I posted the same response in the forum thread linked above.)

If you want auto-wire the Queue try to use JSR-250's @Resource annotation and a reasonable qualifier. Spring supports these annotations and should correctly inject the queue.)

1
2
3
4
5
@Component
public class B {
  @Resource(name="myBlockingQueue")
  private BlockingQueue<Integer> blockingQueue;
}

@Autowired and @Resource behave differently.

Background info can be found in the documentation: Fine-tuning annotation-based autowiring with qualifiers

Spring使用@Autowired不能注入BlockingQueue的有关问题Chris Beams added a comment - 07/Jul/11 6:51 PM

Please see SPR-8519, which aims to address this and a number of other similar issues related to collection autowiring.

Spring使用@Autowired不能注入BlockingQueue的有关问题Marty Kube added a comment - 10/Jul/11 6:16 PM

Great, thanks. @Resource solved the issue.