【问题标题】:Spring @Autowired in ServletServlet 中的 Spring @Autowired
【发布时间】:2010-11-15 12:08:24
【问题描述】:

我在我的应用程序中使用 Spring 框架 (2.5.4) 和 Load time weaving 并且一切工作正常(在 Spring bean 中,在非 Spring 实体中),除非我尝试在注释为 @ 的 servlet 中自动装配字段可配置,然后我得到一个不错的 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" />

关于我做错了什么有什么建议吗?

谢谢。

【问题讨论】:

  • 我不确定,但可能是因为servlet类是由servlet容器而不是spring容器加载的。
  • @abhin4v:加载时编织背后的想法是允许任何东西加载类,而不仅仅是通过 Spring。
  • @malejpavouk,这种行为的最终解决方案是什么,你能分享一下吗?
  • 使用 WebContextUtils 手动查找。我在某处读过,这也可以通过使用 aspectj 代理来解决(但没有尝试过)。我也将此作为错误提交到 Spring JIRA 中,但它已被解决为 wontfix(被设计破坏)。

标签: java spring servlets autowired


【解决方案1】:

这可能是因为 Servlet 正在由 Servlet 容器实例化和初始化, Spring 上下文被初始化之前,它是处理加载时编织的 Spring 上下文。

您的 &lt;context:load-time-weaver/&gt; 内容是在 servlet Spring 上下文中处理/还是在 webapp 级别处理?前者几乎肯定行不通(出于上述原因),但 webapp 级别的配置可能行得通(使用 ContextLoaderListener)。

【讨论】:

  • 我在 web.xml 中使用 contextLoaderLister...似乎一些成功注入的 bean 是在 servlet 之前创建的...
  • context:load-time-weaver 标签本身在 spring 配置文件中...不知道是否重要,但我正在使用 spring-agent 来检测我的代码
【解决方案2】:

另请参阅 mailing list discussion 和 https://bugs.eclipse.org/bugs/show_bug.cgi?id=317874 上的错误报告。我同意直观上 servlet 上的 @Configurable 注释应该足以向 spring 框架表明,当使用 &lt;context:spring-configured/&gt; 时,servlet 在实例化时将由 spring 配置。我还观察到,使用 -javaagent:/path/to/aspectjweaver.jar 而不是 spring-instrument*.jar 或 spring-agent.jar 时,可以实现所需的行为。请在 https://jira.springframework.org/browse/SPR 提出有关 Spring Jira 的问题。我认为问题可能在于 servlet 类 - 不是 servlet 的实例,而是类本身 - 在调用 spring ContextLoaderListener 之前加载,因此 spring 框架没有机会在 servlet 类被调用之前对其进行检测加载。

加载时间编织的弹簧工具似乎基于能够在加载类字节码之前对其进行转换。如果 servlet 容器持有在 spring 转换之前获得的 Class 对象的实例,那么它(servlet 容器)将无法生成转换后的类的实例,spring 也无法检测实例使用该 Class 对象上的工厂方法创建。

【讨论】:

    猜你喜欢
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 2014-12-15
    相关资源
    最近更新 更多