[英]With Spring, how can I inject a child bean in a parent bean?
我有一个想要注入其子类的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
位会使一切按预期方式工作,因此似乎Spring无法找到Child,好像Parent以某种方式对其进行了遮盖一样。 如何配置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类视为其自己的独立实体,缺少哪些成分。 这不可能吗?
我已经通过修改Parent的定义来解决问题,如下所示:
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
来按名称查找bean。
由于Child
扩展了Parent
,因此必须构造一个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 {
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.