Spring autowire по аргументам конструктора имени

У нас есть большие java-приложения с тысячами bean-компонентов, профилируя медленную инициализацию контекста Spring, мы обнаружили, что автоматическое связывание по типу занимает большую часть времени загрузки контекста. Автосвязывание bean-компонента по имени, по-видимому, на порядок улучшает инициализацию контекста. Однако я не смог найти способ автоматического связывания bean-компонентов по имени в качестве аргументов конструктора.

Ниже приведен автопровод участника, который отлично работает, Spring выполняет поиск по имени:

class MyClass {
   @Resource
   private MyBean mybean;
}

Но поскольку @Resource применяется только к членам и методам, он не применяется к конструктору. Мы пробовали как @Inject с @Named, так и @Autowired с @Qualifier, но Spring выполняет медленный поиск по типу для этих подходов:

class MyClass {
   @Inject
   public MyClass(@Named("myBean") MyBean myBean) {
   }
}

class MyClass {

   @Autowired
   public MyClass(@Qualifer("myBean") MyBean myBean) {
   }
}

Как сказать Spring не искать по типу при использовании инъекции конструктора?

Мы понимаем преимущества wire по типу (отделение от имен bean-компонентов), но на данный момент производительность загрузки контекста является нашей самой большой проблемой.


person LiorH    schedule 06.08.2014    source источник
comment
Весь смысл наличия аннотаций (метаданных) в вашем коде заключается в обеспечении безопасного внедрения типов. Вы хотите отказаться от основной функции этого инжектора. Возможно, правильный подход к решению этой проблемы состоит в том, чтобы сделать ваше приложение более модульным, чтобы вам не приходилось создавать один эпически огромный ApplicationContext.   -  person Xorty    schedule 06.08.2014
comment
Почему вы не можете просто настроить эти компоненты в конфигурации?   -  person jny    schedule 06.08.2014


Ответы (1)


Я знаю, что сейчас это немного старомодно, но связывание по имени в xml очень просто, а Spring поддерживает смешивание конфигурации xml и java.

При условии, что bean-компонент myBean определен в xml конфигурации Java, вы можете написать

<bean id="myClass" class="...MyClass">
    <constructor-arg ref = "myBean"/>
</bean>

или в случае нескольких аргументов:

<bean id="myClass" class="...MyClass">
    <constructor-arg index="0" ref = "myBean"/>
    <constructor-arg index="1" ref = "myOtherBean"/>
</bean>

РЕДАКТИРОВАТЬ

В качестве альтернативы в конфигурации Java вы можете:

@Configuration
public class MyClassConfig() {

@Autowire
@Qualifier("myBean")
MyBean myBean;

@Bean
MyClass myclass = new MyClass(myBean);
}

Спасибо jny за предложение.

person Serge Ballesta    schedule 06.08.2014
comment
хорошо, спасибо, я знаю, что могу это сделать, интересно, есть ли способ, которым я могу продолжить подход с компонентным сканированием и подключением, если я могу сказать Spring использовать подключение по имени. - person LiorH; 06.08.2014