Spring MVC: autowire игнорируется в сервлетах

1

По каким-то причинам я могу выполнять аутсорсинг в своих контроллерах, но не в том сервлете, который я создал.

Это верхняя часть моего сервлета:

@Component
public class MyServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

    @Autowired
    private CobiService cobiService;

В моем web.xml это соответствующая конфигурация:

    <servlet>
        <servlet-name>convservlet</servlet-name>
        <servlet-class>com.gim.servlets.MyServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>convservlet</servlet-name>
        <url-pattern>/MyServlet</url-pattern>
    </servlet-mapping>

И так я рассказываю весне для сканирования компонентов:

    <context:component-scan base-package="com.gim" />

По какой-то причине мой автообновленный объект cobiService имеет значение null. Я что-то забыл? Что я должен изменить?

  • 0
    Какое полное имя сервлета? Это в пакете com.gim ?
  • 0
    com.gim.servlets.MyServlet
Теги:
servlets
model-view-controller
spring

3 ответа

3
Лучший ответ

Сервлеты не управляются Spring, они управляются контейнером Servlet (например, Tomcat). Поэтому Spring не может вводить зависимости в сервлеты обычным способом Spring. Однако вы можете сделать что-то вроде следующего:

public class MyServlet extends javax.servlet.http.HttpServlet {

    private CobiService cobiService;

    @Override
    public void init() throws ServletException {
        super.init();
        ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        cobiService = applicationContext.getBean(CobiService.class);
    }

}
  • 0
    Почему бы просто не использовать интерфейс ContextAware ?
  • 0
    Это очень хорошая идея! Вы должны обновить свой ответ с этим кодом!
Показать ещё 3 комментария
1

Вы можете переопределить свой метод init servlet и выполнить

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (this);

SpringBeanAutowiringSupport

Нет необходимости делать

implements javax.servlet.Servlet, поскольку вы расширяете HttpServlet

1

Создано два сервлета. Один создается контейнером сервлета/контейнера Java EE, когда приложение инициализирует и считывает настроенный <servlet> внутри файла web.xml. Другой будет создан, когда контейнер Spring IOC выполняет его компонентное сканирование при инициализации.

В этом случае первый экземпляр не может участвовать в инъекции зависимостей, потому что он не был создан в контейнере Spring IOC. Чтобы участвовать в инъекции зависимостей, bean должен управляться контейнером Spring IOC. Когда контейнер сервлета/контейнер Java EE создает экземпляр сервлета, он не знает контейнер Spring IOC.

К сожалению, когда приходит запрос, который удовлетворяет url-pattern указанному в файле web.xml для сервлета, запрос перенаправляется на первый экземпляр, созданный контейнером сервлета/контейнера Java EE, который не является компонентом, а не кандидатом для автоподготовки.

Если вы должны были удалить сервлет из web.xml и добавить аннотацию @RequestMapping к сервлету, второй экземпляр (который является фактическим компонентом, способным использовать автоподключение), будет использоваться для запросов, заполняющих указанный шаблон url в @RequestMapping, однако в этот момент у вас в значительной степени есть контроллер.

Таким образом, в целом, моя рекомендация заключалась в том, чтобы придерживаться соглашений Spring и использовать класс контроллера. Класс контроллера будет соответствовать функциям сервлета и превышать их.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню