Как определить, какой bean-компонент будет автоматически подключен весной - PullRequest
0 голосов
/ 20 сентября 2019

У меня есть 2 бина одного типа:

@Component("beanA")
public class BeanA implements BaseBean {}

@Component("beanB")
public class BeanB implements BaseBean {}

Этот тип используется в моем сервисе:

@Service
public class MyService {

    @Autowired
    private BaseBean baseBean;
}

Теперь я хочу использовать оба возможных бина MyService в другом сервисе

@Service
public class AnotherService {

    @Autowired
    private MyService myServiceWithBeanA;

    @Autowired
    private MyService myServiceWithBeanB;
}

Как мне этого добиться?Может быть, я должен выбрать другой подход?

Я знаю, как это сделать в конфигурации bean-компонентов на основе XML.Как я могу сделать это, используя аннотации?

<bean id="AnotherService" class="AnotherService">
    <property name="myServiceWithBeanA" ref="myServiceWithBeanA" />
    <property name="myServiceWithBeanB" ref="myServiceWithBeanB" />
</bean>

<bean id="myServiceWithBeanA" class="MyService">
    <property name="baseBean" ref="beanA" />
</bean>

<bean id="myServiceWithBeanB" class="MyService">
    <property name="baseBean" ref="beanB" />
</bean>

<bean id="beanA" class="BeanA" />
<bean id="beanB" class="BeanB" />

Ответы [ 4 ]

2 голосов
/ 20 сентября 2019

Проблема в том, что MyService помечен @Service.Это означает, что это синглтон - будет создан только один экземпляр.

Чтобы создать несколько экземпляров, вам необходимо выставить два @Bean с помощью конфигурации.

@Configuration
public class MyServiceConfig {
    @Bean
    public MyService serviceA(@Qualifier("beanA") beanA) {
        return new MyService(beanA);
    }

    @Bean
    public MyService serviceB(@Qualifier("beanB") beanB) {
        return new MyService(beanB);
    }
}

MyService станет

public class MyService {
    private BaseBean baseBean;

    public MyService(BaseBean baseBean) {
        this.baseBean = baseBean;
    }
}

Затем все это можно передать другой службе с квалификаторами

@Service
public class AnotherService {

    @Autowired
    @Qualifier("serviceA")
    private MyService myServiceWithBeanA;

    @Autowired
    @Qualifier("serviceB")
    private MyService myServiceWithBeanB;
}
0 голосов
/ 20 сентября 2019

Не все можно сделать с аннотациями.В случаях, когда вам нужно создать несколько экземпляров bean-компонента, но с разными аргументами, вы должны вернуться к @ Configuration и определить эти bean-компоненты как в конфигурации XML.

@Configuration
public class AppConfig {

    @Bean
    public MyService myServiceWithBeanA(BeanA beanA) {
        return new MyService(beanA);
    }

    @Bean
    public MyService myserviceWithBeanB(BeanB beanB) {
        return new MyService(beanB);
    }

}

Теперь просто скажите AnotherService, что следует ожидать MyService дважды с совпадающими именами компонентов, поскольку имя метода определения компонента является его квалификатором по умолчанию.

@Service
public class AnotherService {

    @Autowired
    private MyService myServiceWithBeanA;

    @Autowired
    private MyService myServiceWithBeanB;
}
0 голосов
/ 20 сентября 2019

В вашем определении xml bean добавьте эти теги <qualifier value="name"/>.

<bean id="myServiceWithBeanA" class="MyService">
    <qualifier value="A"/>
    <property name="baseBean" ref="beanA" />
</bean>

<bean id="myServiceWithBeanB" class="MyService">
    <qualifier value="B"/>
    <property name="baseBean" ref="beanB" />
</bean>

И затем вы можете получить их, используя Qualifier аннотацию, подобную этой:

@Autowired
@Qualifier("A")
private MyService myServiceWithBeanA;

@Autowired
@Qualifier("B")
private MyService myServiceWithBeanB;

Вы также можете делать больше вещей, чем это.Посмотрите документацию по следующей ссылке: Документация для уточнения

0 голосов
/ 20 сентября 2019

Используя аннотацию @Qualifier, вы можете указать, какой бин вы хотите автоматически подключать.

@Service
public class AnotherService {

    @Autowired
    @Qualifier("beanA")
    private MyService myServiceWithBeanA;

    @Autowired
    @Qualifier("beanB")
    private MyService myServiceWithBeanB;
}

Надеюсь, это поможет.

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