2014-01-20 6 views
0

Ниже мой контроллер. Моя программа генерирует вывод на основе ввода формы. В рамках проекта существует несколько форм ввода, которые генерируют выходной объект. Итак, основной поток тот же. Поэтому я хочу, чтобы один контроллер нескольких действий выполнял все это.Весенний автопоезд под переменным именем

Вызовы: 1. Классы обслуживания меняются. Хотя все службы реализуют один и тот же интерфейс, а контроллер вызывает тот же метод интерфейса. 2. Объекты ввода меняются. Хотя входные объекты не имеют других методов, кроме сеттеров и геттеров. Поэтому я позволил им реализовать пустой интерфейс.

Вопросы:

  1. Как изменить классификатор, основанный на пути. Могу ли я использовать переменные пути?

  2. Предположим, что путь имеет это значение -> singleton. Тогда мои соответствующие имена компонентов будут singletonService и singletonInput. Я хочу создать постоянный класс, который хранит эту информацию сопоставления. Итак, могу ли я назвать это изнутри квалификатора, используя некоторый язык выражения Spring? Пример, вместо Qualifier (variablePathName) -> Qualifier (getQualifierName ['variablePathName']) Что-то вроде этого?

  3. Просьба также разъяснить теорию этого. Из того, что, как я понимаю, создаются бобы, автоуведомленные перед отображением запроса ... Означает ли это, что то, чего я пытаюсь достичь здесь, просто невозможно. В таком случае предложите ли вы создать пары Controller-service для обработки каждого запроса, в основном с тем же кодом? Но я чувствую, что должен быть какой-то способ добиться того, что я пытаюсь ...

Код:

@Cotroller 
@RequestMapping(value="/generate/{path}") 
public class TestController { 

    @Autowired 
    @Qualifier(......) 
    private IService service; 

    @Autowired 
    @Qualifier(......) 
    IUserInput userInput; 

    @RequestMapping(method = RequestMethod.POST) 
    //Some handler method 
} 

ответ

2

Вы правы в том, что все автоматического связывания выполняется один раз вперед (пункт 3). Вы не сможете достичь того, что хотите, используя поля, аннотированные @Autowired и @Qualifier - поскольку эти поля всегда ссылаются на один и тот же экземпляр компонента.

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

@Cotroller 
@RequestMapping(value="/generate/{path}") 
public class TestController { 

    @Autowired 
    private ApplicationContext applicationContext; 

    @RequestMapping(method = RequestMethod.POST) 
    public String someHandlerMethod(@PathVariable String path) { 
     IService service = (IService) applicationContext.getBean(path + "Service"); 
     IUserInput userInput = (IUserInput) applicationContext.getBean(path + "UserInput"); 

     // Logic using path specific IService and IUserInput 
    } 
} 
+0

спасибо. Думаю, это сработает. У меня возникло сомнение, будет ли это требовать от меня настройки XML (чего я не хочу), или я могу просто аннотировать мои классы обслуживания как @Service («pathService»)? И как я должен аннотировать мой класс UserInput? С @Bean ("pathUserInput") или @Component ("pathUserInput")? – Nikhil

+1

Вы должны уметь комментировать ваши классы и следить за тем, чтобы их подхватили с помощью '', поэтому не нужно использовать XML. Имя службы по умолчанию, используемое Spring, - это имя класса, но с строчной первой буквой, но если это не то, что вы хотите, вы можете явно передать имя, например '@Service (« pathService »). Вы также можете сделать это с вашими объектами ввода и аннотировать эти '@Component (" pathUserInput ")' –

+0

. При использовании applicationContext таким образом я получаю NoSuchBeanDefinitionException, хотя он существует. Я аннотировал классы с помощью '@ Component' и' @ Service'. Если я вручную настрою эти компоненты в конфигурации на основе XML/Java с помощью '@ Configuration', это сработает ... Почему bean-компоненты не читаются ApplicationContext. Я что-то упускаю? – Nikhil

Смежные вопросы