Spring @Autowired в сервлете - PullRequest
       24

Spring @Autowired в сервлете

5 голосов
/ 15 ноября 2010

Я использую Spring Framework (2.5.4) в своем приложении с переплетением времени загрузки, и все отлично работает везде (в компонентах Spring, в объектах, отличных от Spring), кроме случаев, когда я пытаюсь автоматически связать поле в сервлете, аннотированном как @ Конфигурируемый, тогда я получаю хорошее NullPointerException ...


@Configurable(dependencyCheck=true)
public class CaptchaServlet extends HttpServlet{
    @Autowired
    private CaptchaServiceIface captchaService;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    //    ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
    //    captchaService = (CaptchaServiceIface) ctx.getBean("captchaService");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Captcha c = captchaService.getCatpcha();
        req.getSession().setAttribute("captchaAnswer", c.getAnswer());
        resp.setContentType("image/png");
        ImageIO.write(c.getImage(), "png", resp.getOutputStream());
    }
}

<context:load-time-weaver/>
<context:spring-configured/>
<context:component-scan base-package="cz.flexibla2" />

Есть предложения о том, что я делаю неправильно?

Спасибо.

Ответы [ 2 ]

6 голосов
/ 15 ноября 2010

Вероятно, это связано с тем, что сервлет создается и инициализируется сервлет-контейнером, за до инициализируется контекст Spring, а контекст Spring обрабатывает время загрузки.

Ваши <context:load-time-weaver/> вещи обрабатываются внутри контекста Spring сервлета или на уровне веб-приложения?Первый почти наверняка не будет работать (по причинам, указанным выше), но конфигурация уровня веб-приложения может работать (используя ContextLoaderListener).

3 голосов
/ 07 декабря 2010

См. Также обсуждение списка рассылки и отчет об ошибках по адресу https: // bugs.eclipse.org/bugs/show_bug.cgi?id=317874.Я согласен, что интуитивно аннотации @Configurable на сервлете должно быть достаточно, чтобы указать платформе пружины, что сервлет при создании экземпляра будет сконфигурирован пружиной при использовании <context:spring-configured/>.Я также заметил, что желаемое поведение достижимо при использовании -javaagent: /path/to/aspectjweaver.jar вместо spring-instrument * .jar или spring-agent.jar.Пожалуйста, поднимите вопрос с Spring Jira на https: // jira.springframework.org/browse/SPR.Я полагаю, что проблема может заключаться в том, что класс сервлета - не экземпляр сервлета, а сам класс - загружается до вызова пружины ContextLoaderListener, поэтому среда Spring не имеет возможности инструктировать класс сервлета до егозагружен.

Похоже, что инструментальные средства пружины для ткачества во время загрузки основаны на способности преобразовывать байт-код класса перед его загрузкой.Если контейнер сервлета удерживает экземпляр объекта Class, который был получен до того, как он был преобразован пружиной, то он (контейнер сервлета) не сможет создавать экземпляры преобразованного класса, а Spring не сможет обрабатывать экземпляры.создан с использованием фабричных методов для этого объекта Class.

...