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

Я использую инфраструктуру Spring (2.5.4) в своем приложении с плетением времени загрузки, и все работает нормально везде (в компонентах Spring, в объектах, отличных от Spring), за исключением случаев, когда я пытаюсь автоматически связать поле в сервлете, аннотированном как @Configurable, затем Я получаю хорошее исключение 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" />

Любые предложения о том, что я делаю неправильно?

Спасибо.


person malejpavouk    schedule 15.11.2010    source источник
comment
Я не уверен, но это может быть потому, что класс сервлета загружается контейнером сервлета, а не контейнером Spring.   -  person Abhinav Sarkar    schedule 15.11.2010
comment
@abhin4v: Идея плетения во время загрузки состоит в том, чтобы разрешить загрузку класса чему угодно, а не только Spring.   -  person skaffman    schedule 15.11.2010
comment
@malejpavouk, какое окончательное решение для такого поведения, не могли бы вы поделиться им?   -  person Mahmoud Saleh    schedule 07.08.2012
comment
Ручной поиск с использованием WebContextUtils. Я где-то читал, что это также можно исправить с помощью агента аспекта (но не пробовал). Я также зарегистрировал это как ошибку в Spring JIRA, но она была устранена как неисправленная (сломанная по дизайну).   -  person malejpavouk    schedule 07.08.2012


Ответы (2)


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

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

person Larry Chu    schedule 07.12.2010

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

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

person skaffman    schedule 15.11.2010
comment
Я использую contextLoaderLister в web.xml... и кажется, что некоторые bean-компоненты, успешно внедренные, создаются до сервлета... - person malejpavouk; 16.11.2010
comment
сам тег context:load-time-weaver находится в файле конфигурации spring... Не знаю, важно ли это, но я использую spring-agent для инструментария своего кода - person malejpavouk; 16.11.2010