[英]Spring Bean Wiring
我正在学习Spring的基础知识,现在我正在研究Beans /接线。 这个问题可能没有意义,这只是我在阅读/尝试Craig Walls的“Spring into Action”一书中的一些例子之后想到的。 说有这个界面。
public interface CompactDisc {
void play()
}
我有两个实现此接口的类。
public class HybridTheory implements CompactDisc { }
public class Meteora implements CompactDisc { }
我的配置类使用组件扫描并从这两个类创建bean。 现在,如果我有一个具有光盘实例的测试类,并使用自动连接进行连线
public class myTest {
@Autowired
private CompactDisc cd;
}
会有问题吗? 我的问题是,你如何连接它,以便它使用一个bean而不是另一个? 或者这不是真实情况/我应该创建特定类的属性,而不是接口的属性? 我想我只是难以绕着布线缠绕我的脑袋。
每当遇到有多个实现相同接口的情况时,您可以采取的方法很少。
1.使用@Qualifier注释
如果您使用类路径扫描,您的类可能如下所示:
@Component
public class HybridTheory implements CompactDisc { }
@Component
public class Meteora implements CompactDisc { }
每个Spring bean都获取一个由容器分配的id,默认情况下它是一个以较小字母开头的类名。 如果这两个组件将是:
hybridTheory
meteora
您可能还希望通过将name
参数传递给@Component注释来选择自定义名称,例如: @Component("myFavLinkinParkAlbum")
。
然后,每当你自动装配CompactDisc
bean时,你都可以传递@Qualifier注释并告诉Spring你想到的是哪个bean。
@Service
class Player {
private final CompactDisc compactDisc;
// note that starting from Spring 4.3
// you can omit @Autowired annotation from constructor
Player(@Qualifier("hybridTheory") CompactDisc compactDisc) {
this.compactDisc = compactDisc;
}
}
2.将您的一个bean标记为@Primary
如果在大多数注射点注射总是相同的豆而另一个很少使用,您可以考虑使用@Primary标记前者。
@Component
@Primary
public class HybridTheory implements CompactDisc { }
每当Spring发现有多个bean匹配注入点时,它将注入一个用@Primary注释的bean 。 请注意,如果有多个使用@Primary注释的bean并且实现了注入点中使用的接口,问题仍然存在。
3.使用Java配置
虽然@Qualifier和@Primary有时会解决问题,但您可能会发现要了解注入了哪些实现,您需要通过源代码大量旅行。 有时候更干净的方法是从类中删除@Component (或其他构造型注释)并使用Java配置声明bean:
public class HybridTheory implements CompactDisc { }
public class Meteora implements CompactDisc { }
@Configuration
class RecordsConfiguration {
@Bean
CompactDisc hybridTheory() {
return new HybridTheory();
}
@Bean
CompactDisc meteora() {
return new Meteora();
}
@Bean
Player player() {
return new Player(meteora());
}
}
选择最适合您用例的产品!
一种简单而优雅的方法是尽可能使用byType 。 当那是不可能的,可以使用的绰号方法。
使用它的一种方法是手动命名bean - 然后在更改类名后bean名称不会有所不同。 请注意,只有在具有相同类型的多个实现时才应使用命名bean,否则不需要命名。 在下面的示例中,命名是注释的一部分,例如@Component("hybridTheory")
。 这意味着您可以将HybridTheory
的类名HybridTheory
为您想要的任何名称,并且bean名称仍然是hybridTheory
。
当您通过名称注入某些内容时 ,可以使用@Qualifier
批注指定所需的命名bean。 我个人更喜欢@Resource
因为你可以在构造函数中使用@Qualifier
(我更喜欢构造函数注入而不是基于setter和field的注入)。
你不应该注入的具体类型-这就是依赖注入是怎么一回事。 其他人(即Spring)将为您处理对象创建;)
public interface CompactDisc {
void play();
}
@Component
class CompactDiscPlayer {
@Autowired
CompactDiscPlayer(@Qualifier("hybridTheory") final CompactDisc compactDisc) {
// The bean of type HybridTheory will be used
compactDisc.play();
}
}
@Component("hybridTheory")
class HybridTheory implements CompactDisc {
public void play() {
System.out.println(getClass().getSimpleName());
}
}
@Component("meteora")
class Meteora implements CompactDisc {
public void play() {
System.out.println(getClass().getSimpleName());
}
}
Spring的文档描述了各种选项在这里 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.