通过Spring Boot @Configuration连接具有相同依赖性的多个bean

时间:2017-04-12 19:02:29

标签: spring-boot dependency-injection

在较旧的Spring MVC应用程序中,您指定application.xml并声明应用程序的bean,以便Spring DI可以实例化它们并将它们连接在一起,您可能会有这样的事情:

<bean id="chargeFactory" class="com.example.myapp.ChargeFactory" />

<bean id="paymentService" class="com.example.myapp.DefaultPaymentService">
  <ref id="chargeFactory"/>
</bean>

<bean id="chargeAuditor" class="com.example.myapp.ChargeAuditor">
  <ref id="chargeFactory"/>
</bean>

这可能有助于连接以下代码:

public interface PaymentService {
    public void makePayment(Payment payment);
}

public class DefaultPaymentService implements PaymentService {
    @Autowired
    private ChargeFactory chargeFactory;

    @Override
    public void makePayment(Payment payment, String key) {
        Charge charge = chargeFactory.createCharge(key);
        charge.doCharge(payment);
    }
}

public class ChargeAuditor {
    @Autowired
    private ChargeFactory chargeFactory;

    public void auditAllCharges(String key) {
        List<Charge> charges = chargeFactory.getAllCharges(key);
        // blah whatever
    }
}

如何使用@Configuration类在Spring Boot中完成相同的bean连接?例如:

@Configuration
public class MyAppInjector {
    @Bean
    public ChargeFactory chargeFactory() {
        return new ChargeFactory();
    }

    @Bean
    public PaymentService paymentService() {
        return new DefaultPaymentService(chargeFactory());
    }

    @Bean
    public ChargeAuditor chargeAuditor() {
        return new ChargeAuditor(chargeFactory());
    }
}

可能有效,但会引入一些问题:

  1. 这将迫使我必须为我的所有类编写值构造函数,这与我在字面上看到的所有每个教程/文章中遇到的所有内容都不相符。另外,如果我必须这样做,那么@Autowired无论如何都没有真正的价值......
  2. 此时我基本上都在做“DIY DI”,这是好的,除了我试图刻意使用Spring DI: - )
  3. 每次调用chargeFactory()时,我都会收到一个新的(原型样式)ChargeFactory实例。也许我想要一个单身人士。使用这种方法,我必须手动滚动我自己的单例实现。
  4. 当然,我可以做所有这些,但我觉得我公然滥用/误解@Configuration应该如何使用,因为我似乎在介绍一大堆DIY /自制的代码来解决Spring DI应该能为我做的事情。

    我如何引用chargeFactory bean并将其连接到paymentServicechargeAuditor bean的“提供者方法”中?再次,寻找基于Java的@Configuration解决方案,而不是编写XML文档来定义布线。

    我发现this article似乎是通过@Configuration连接Spring Boot应用程序的唯一教程/文档(令人惊讶)(这让我相信可能还有其他/更好的方法......) ,但它没有解决:

    • 如何指定单例与原型bean实例化模式
    • 如果存在多个bean类实例,如何指定将哪个实例连接到哪个依赖项?
    • 如何解决所有我的类的值构造函数,让Spring / @Autowired自动注入字段?

1 个答案:

答案 0 :(得分:1)

当你调用chargeFactory()时,spring不会每次都创建新实例。试试看吧。将返回相同的对象。无论如何 你可以做这样的事情。

@Bean 
public PaymentService paymentService(ChargeFactory chargeFactory) { return new DefaultPaymentService(chargeFactory); }