Подтвердить что ты не робот

Spring Javaconfig inter- bean зависимости

Просмотр справочной документации по Spring Javaconfig http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html Я нашел некоторые запутанные части...

В разделе "5.12.4 Используя аннотацию @Configuration" , он говорит:

"Когда @Beans имеют зависимости друг от друга, выражение, что зависимость так же просто, как один метод bean вызывает другое:

@Configuration
public class AppConfig {
    @Bean
    public Foo foo() {
        return new Foo(bar());
    }
    @Bean
    public Bar bar() {
        return new Bar();
    }
}

В приведенном выше примере foo bean получает ссылку на бар через инъекцию конструктора. "

Ну, если все без гражданства, это может не иметь особого значения, но если у вас есть конфигурация выше, а затем в вашем приложении:

@Autowired 
private Foo foo;

@Autowired 
private Bar bar;

проверка хэш-кодов beans, оказывается, что ваша личная переменная bar будет ссылаться на другой экземпляр Bar, чем тот, который используется Foo, вероятно, не так, как вы ожидаете, правильно?

Я бы сказал, что нормальная картина должна быть:

@Configuration
public class AppConfig {
    @Bean
    public Bar bar() {
        return new Bar();
    }
    @Autowired Bar bar;
    @Bean
    public Foo foo() {
        return new Foo(bar);
    }
}

Теперь, когда вы автоматически используете beans в своем приложении, вы создадите только один экземпляр панели.

Я что-то упустил, или я исправлю, что документация здесь шероховатая?

Затем далее в разделе "Дополнительная информация о том, как конфигурация на основе Java работает внутри" похоже, они пытаются "прояснить" эту проблему:

@Configuration
public class AppConfig {
    @Bean
    public ClientService clientService1() {
        ClientServiceImpl clientService = new ClientServiceImpl();
        clientService.setClientDao(clientDao());
        return clientService;
    }
    @Bean
    public ClientService clientService2() {
        ClientServiceImpl clientService = new ClientServiceImpl();
        clientService.setClientDao(clientDao());
        return clientService;
    }
    @Bean
    public ClientDao clientDao() {
        return new ClientDaoImpl();
    }
}

Теперь, к сожалению, эта конфигурация даже не загружается во время выполнения, потому что есть 2 beans того же типа, ClientService, без каких-либо отличительных свойств, поэтому получите исключение

org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type [.....] is defined: 
expected single matching bean but found 2

Но даже если мы слегка изменим пример и дадим первые 2 beans разные типы,

@Bean
public ClientService1 clientService1() {...clientDao()...}
@Bean
public ClientService2 clientService2() {...clientDao()...}
@Bean
public ClientDao clientDao() {
    return new ClientDaoImpl();
}

это все еще некорректно, поскольку, вопреки тому, что утверждает текст, мы все равно создадим 3 разных экземпляра ClientDaoImpl, при автопостановке всех 3 beans.

Опять же, я вообще что-то пропущу, или документация действительно такая же плохая, как мне кажется?

EDIT: Добавлена ​​демонстрация, которая продемонстрирует проблему, которую я вижу:

https://github.com/rop49/demo

A bean ServiceA, и два beans ServiceB1, ServiceB2, которые конструктор вводит ServiceA.

Затем два тестовых класса Config01Test и Config02Test идентичны, за исключением конфигураций. Первый тест PASSES, второй FAILS из-за уникальности - утверждает.

4b9b3361

Ответ 1

Убедитесь, что у вас есть @Configuration аннотации в вашем классе конфигурации. С вашей демонстрацией, по крайней мере, они отсутствуют в классах Config01 и Config02. Если я добавлю их в те классы, тесты пройдут.

Ответ 2

Я не тестировал сам пример. Это должно убедиться, что у вас есть только один экземпляр Bar в полном контексте приложения.

@Configuration
public class AppConfig {
    @Bean
    public Foo foo(Bar bar) {
        return new Foo(bar);
    }
    @Bean
    public Bar bar() {
        return new Bar();
    }
}