Внедрение зависимостей Spring с дублирующимися компонентами и аннотацией @Order - PullRequest
0 голосов
/ 20 июня 2019

Я слегка растерялся из-за механизма инжекции DI в Spring, когда у меня несколько бинов с одинаковым именем / типом.Согласно слайдам экзаменов из курса «Основной источник» в Pivotal, поведение Spring с одинаковыми бобами можно свести к следующему:

  • Один и тот же бин можно определить более одного раза
  • Внедрения Springbean-компонент, определенный последним
  • Используя @Order, механизм загрузки (и, следовательно, какой бин загружается последним) можно изменить

Однако в следующем примере Spring будет игнорироватьлюбые аннотации @Order и внедрение компонента из класса Config, который последний раз упоминался в операторе @Import.Поэтому мне интересно, переопределяет ли порядок классов конфигурации в аннотации @Import какие-либо аннотации @Order.Или я упускаю еще один важный момент?Любые намеки высоко ценятся.Благодаря переполнению стека!

Основной класс конфигурации

@Configuration
@Import({RogueConfig.class,RewardsConfig.class})
public class TestInfrastructureConfig {
  // nothing interesting here, just importing configs
}

RewardsConfig

@Configuration
@Order(1)
public class RewardsConfig {
    @Bean
    public RewardNetwork rewardNetwork() {
        System.out.println("This Bean has been loaded from: " + this.getClass().getName());
        return new RewardNetworkImpl(null, null, null);
    }
}

RogueConfig

@Configuration
@Order(2)
public class RogueConfig {
    @Bean
    public RewardNetwork rewardNetwork() {
        System.out.println("This Bean has been loaded from: " + this.getClass().getName());
        return new RewardNetworkImpl(null, null, null);
    }
}

Тестовый класс

public class RewardNetworkTests {

    ApplicationContext applicationContext;

    @BeforeEach
    void setUp() {
        applicationContext = SpringApplication.run(TestInfrastructureConfig.class);
    }

    @Test
    void injectingRewardNetworkBeanWithOrdering() {
        RewardNetwork rewardNetwork = applicationContext.getBean(RewardNetwork.class);
        assertNotNull(rewardNetwork);
    }
}

Независимо от того, какие значения я присваиваю @Order или, если я вообще использую упорядочение, результат всегда будет:

This Bean has been loaded from: config.RewardsConfig$$EnhancerBySpringCGLIB$$62461c55

Единственный способ изменить это - изменить аннотацию импорта в моем TestInfrastructureConfig следующим образом:

@Import({RewardsConfig.class,RogueConfig.class}), что дает:

This Bean has been loaded from: config.RogueConfig$$EnhancerBySpringCGLIB$$6ca7bc89

Мне интересно, что нужно сделать, чтобы значения, определенные в @Order, имели какой-либо эффект.

1 Ответ

0 голосов
/ 20 июня 2019

Мне удалось заставить Spring использовать аннотации @Order, загружая конфигурации напрямую (т.е. без обхода через класс @Configuration с использованием @Import):

@SpringJUnitConfig({RogueConfig.class, RewardsConfig.class})
public class CdiTest {

    @Test
    public void testCdiWithIdenticalBeans(@Autowired RewardNetwork rewardNetwork) {
        assertThat(rewardNetwork).isNotNull();
    }
}

С@Order(2) аннотация в классе RogueConfig , этот боб был загружен последним, как показано в stdout:

This Bean has been loaded from: config.RogueConfig$$EnhancerBySpringCGLIB$$552b937f

Кажется, что при использовании @Importв конфигурационных классах он загружает определения bean-компонентов в порядке, указанном в аннотации, что делает бесполезными любые аннотации @Order в соответствующих классах конфигурации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...