繁体   English   中英

春豆接线

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM