Spring-Wicket: необязательно, но именованный боб все еще требуется
Рассмотрим следующий (калитка) код:
@SpringBean(required=false)
private StatusCheckService service;
В моем случае использования в моем контексте нет компонента типа StatusCheckService. Это не проблема, она помечена как необязательная, поэтому страница (wicket) будет хорошо инициализироваться.
Тем не мение:
@SpringBean(name = "statusCheckService", required=false)
private StatusCheckService service;
Это не удается:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'statusCheckService' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:400)
at org.springframework.context.support.AbstractApplicationContext.isSingleton(AbstractApplicationContext.java:1113)
at org.apache.wicket.spring.SpringBeanLocator.isSingletonBean(SpringBeanLocator.java:100)
at org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getFieldValue(AnnotProxyFieldValueFactory.java:140)
Я ожидаю, что это не имеет значения. ОК, бин с таким именем не существует, но я отметил его как необязательный, так почему исключение? Есть ли способ обойти это?
1 ответ
Выполнив поиск использования в eclipse, вы увидите, что единственный раз, когда аннотация запрашивается для ее требуемого значения, находится в строке 215 AnnotProxyFieldValue:
if (names.isEmpty())
{
if (annot.required())
{
throw new IllegalStateException("bean of type [" + clazz.getName() + "] not found");
}
return null;
}
Здесь вы можете видеть, что поле 'required' аннотации @SpringBean используется только в том случае, если список имен (установлен выше в функции) пуст...
Это объясняет поведение, которое вы испытываете, потому что, когда вы не указываете имя, список имен становится пустым (потому что он не может найти ваш класс), и возвращается ноль. Однако, когда вы указываете имя, оно не беспокоится о том, чтобы увидеть, существует ли класс, и поэтому отправляет предоставленное имя класса для весны, чтобы посмотреть, что продолжает жаловаться, когда он не может найти класс.
Это может быть ошибкой в зависимости от намерений дизайнеров, лично я думаю, что если вы указали, что поле не является обязательным, функция должна вернуться рано... Если вы согласны, то, возможно, рассмотрите возможность быстрого запуска билета jira.
Что касается решения, вы не упомянули много о вашем сценарии использования и о том, почему вам нужно установить имя, даже если вам не требуется, чтобы бин вводился. Но предполагая, что вы делаете это для динамического внедрения компонента на основе определенных критериев, вы можете сделать что-то вроде следующего: (не проверено)
В вашем классе, где внедряется SpringBean, замените:
@SpringBean(name="statusCheckService", required=false)
private StatusCheckService service;
С:
MyCustomSpringBeanInjector injectedService;
И тогда класс MyCustomSpringBeanInjector выглядит примерно так:
import org.apache.wicket.injection.Injector;
import org.apache.wicket.spring.injection.annot.SpringBean;
public class MyCustomSpringBeanInjector
{
@SpringBean public StatusCheckService service;
public MyCustomSpringBeanInjector()
{
Injector.get().inject(this);
}
}
Затем вернитесь в класс, в который вставлялся SpringBean, поместите что-то вроде:
if(statusCheckServiceRequired)
injectedService = new MyCustomSpringBeanInjector();
и заменить "сервис". с "injectedService.service", где это необходимо.
Очевидно, это исправление qwik-e на моей голове, и я уверен, что есть лучший способ сделать это, но вы поняли идею!:)
Удачи!