2016-04-04 7 views
0

У меня есть Bean, который хочет, чтобы ввести его дочерние классы, как так:С весной, как я могу вставить дочерний компонент в родительский компонент?

Родитель:

package test; 

@Component 
public class Parent { 
    @Autowired 
    Child child; 

    public Child getChild() { 
    return child; 
    } 
} 

Ребенок:

package test; 

@Component 
public class Child extends Parent { 
} 

Это приводит к следующей ошибке:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [test.Child] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency 

Извлечение бит extends Parent вызывает все t o работайте так, как ожидалось, поэтому похоже, что Spring не может найти Ребенка, как будто родитель как-то затеняет его. Как настроить Spring для правильной проводки этих дочерних экземпляров? Я использую конфигурацию класса Java, как следующее:

@Configuration 
@ComponentScan(basePackages = "test") 
public class AppConfig { 
} 

Я пытался играть вокруг с @Qualifier аннотацию и назначая различные имена в пределах AppConfig, как и в дальнейшем, что не помогло:

@Bean(name = "parent") 
public Parent parent() { 
    return new Parent(); 
} 

@Bean(name = "child") 
public Child child() { 
    return new Child(); 
} 

Я не уверен, что недостающий ингредиент предназначен для того, чтобы заставить Spring увидеть класс Child как свою отдельную сущность. Разве это невозможно?

ответ

2

Я решил проблему по определению модифицирующих Родителя следующим образом:

package test; 

@Primary 
@Component 
public class Parent { 
    @Resource 
    Child child; 

    public Child getChild() { 
    return child; 
    } 
} 

А также модификации ребенка следующим образом:

package test; 

@Component("child") 
public class Child extends Parent { 
} 

я заменил @Autowired аннотацию с @Resource, который пытается на поиск по имени, прежде чем тип, и добавил явное имя класса ребенка. Чтобы устранить проблему родителя от ребенка при попытке выполнить аутсорсинг родителя, я также добавил аннотацию @Primary к родительскому элементу.

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

+0

Это не удается мне, @ user108471, с начальной ошибкой; Я использую Spring Boot 1.3.3 & JDK 8, который использует Spring 4.2.5 для Linux. –

+0

@JanNielsen Извините, похоже, что я забыл другое, важное, изменение: добавление явного имени дочернему классу. – user108471

0

Child Так проходит Parent, A Parent должна быть построена, чтобы построить Child но Parent требует Child для строительства. Это круговая зависимость; избегайте создания циклических зависимостей в коде.

Вам необходимо будет реорганизовать ваш код. Это не может быть возможно в вашей кодовой базе, но если вы можете инвертировать отношения так Parent расширяет Child (а не наоборот, как у вас есть сейчас), вы будете иметь возможность вводить:

package hello; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.annotation.Bean; 
import org.springframework.stereotype.Component; 

@SpringBootApplication 
public class Application { 
    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
    @Autowired 
    private Parent parent; 
    @Bean 
    Child makeChild() { return new Child(); } 
} 
@Component 
class Parent extends Child { 
    @Autowired 
    private Child child; 

    public Child getChild() { return this.child; } 
} 
class Child { 
} 

В качестве альтернативы , реорганизовать код, как Child и Parent нужно в другой класс и впрыснуть этот код в Parent и Child:

package hello; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.annotation.Bean; 
import org.springframework.stereotype.Component; 

@SpringBootApplication 
public class Application { 
    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
    @Autowired 
    private Parent parent; 
    @Bean 
    Child makeChild() { return new Child(); } 
    @Bean 
    Shared makeShared() { return new Shared(); } 
} 
@Component 
class Parent { 
    @Autowired 
    private Shared shared; 
    @Autowired 
    private Child child; 
    public Child getChild() { return this.child; } 
} 
class Child { 
    @Autowired 
    private Shared shared; 
} 
class Shared { 
} 
+0

Пожалуйста, простите меня, но я не понимаю часть вашего фрагмента кода, которая фактически решает проблему.Я вижу, что вы удалили аннотацию '@ Component' на Child, но делать то же самое на моих изменениях ничего. Вы также создали новый класс и опустили один из классов в моем вопросе, и я не понимаю, как это изменит решение. – user108471

+0

Я пропустил 'extends Parent' на' Child' - это создает круговую зависимость, поэтому вы видите эту проблему. Я уточню свой ответ. –

+0

Похоже, я сразу же взглянул на это упущение. – user108471