Spring Autowiring работает только с интерфейсом - PullRequest
16 голосов
/ 28 июня 2011

Я совсем новичок в Spring Framework и столкнулся со следующей проблемой.

У меня есть интерфейс ClassA, который реализован в классах ClassA1 и ClassA2.

У меня добавлено следующее определение bean-компонента к applicationContext.xml

<bean id="class1" class="com.abc.ClassA1" />
<bean id="class2" class="com.abc.ClassA2" />

Я хотел бы автоматически связать оба класса реализации, как показано ниже.

@Autowired
private ClassA1 classA1;

@Autowired
private ClassA2 classA2;

Приведенный выше код выдает ошибку как

Не удалось автоматически записать в поле: com.abc.ClassA1 com.abc.SomeClass.classA1;Вложенное исключение - org.springframework.beans.factory.NoSuchBeanDefinitionException: Нет подходящего компонента типа [com.abc.ClassA1]

Но, если я изменю автоматическое подключение к интерфейсу, как показано ниже:

@Autowired
ClassA classA1;

Затем ClassA1 автоматически подключается к переменной.Я не знаю, как мне автоматически связать переменную с ClassA2.

Ответы [ 6 ]

13 голосов
/ 28 июня 2011

По какой-то причине ваши классы проксируются Spring.Есть много причин, почему это может произойти.Например, если вы используете JPA или AOP, исходный класс проксируется.

Если класс реализует интерфейс, прокси означает Dynamic Proxy.Таким образом, в основном создается новый класс во время выполнения, который реализует интерфейсы, но не наследует от исходного класса.Поэтому автоматическое подключение к исходному классу не работает.

6 голосов
/ 29 июня 2011

Если ваши объекты прокси прокси-серверами JDK, на них должен ссылаться их интерфейс.Вы можете создавать прокси по конкретному классу, используя CGLIB (на пути к классам) и proxy-target-class="true" в вашей конфигурации AOP (в applicationContext.xml)

3 голосов
/ 29 июня 2011

Я пытался решить эту проблему несколькими способами, но у меня все получилось следующим образом.

@Autowired
private ClassA classA1;

@Autowired
private ClassA classA2;

В контексте приложения я определил компонент следующим образом:

<bean id="classA1" class="com.abc.ClassA1" autowire="byName" />
<bean id="classA2" class="com.abc.ClassA2" autowire="byName" />
1 голос
/ 26 августа 2011

Вы можете использовать аннотацию @Qualifier:

@Autowired
@Qualifier("class1")
ClassA classA1;

@Autowired
@Qualifier("class2")
ClassA classA2;

Ref: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-autowired-annotation-qualifiers

или аннотацию @Resource:

@Resource(name="class1")
ClassA classA1;

@Resource(name="class2")
ClassA classA2;

Ref:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-resource-annotation

0 голосов
/ 24 февраля 2017

Из того небольшого, что я видел до сих пор, нет никаких ограничений в отношении типа класса, который можно пометить как @ Autowired.

Не относится к проблеме, но эта статья ссылается на саму ситуацию

0 голосов
/ 03 июля 2014

У меня похожая проблема с абстрактным сервисом Autowiring. Вы можете без проблем использовать код, подобный этому:

@Autowired
@Qualifier("classA1")
private ClassA1 classA1;

@Autowired
@Qualifier("classA2")
private ClassA2 classA2;

Это будет работать, только если вы объявите свой боб таким образом

<bean id="class1" class="com.abc.ClassA1" />

Или вот так

@Component("classA1")
public class ClassA1 {
...
}
...