为什么不在Spring工作中自动装配GWT servlet中的字段?

时间:2012-01-19 21:44:54

标签: spring gwt aspectj autowired configurable

在GWT servlet中简单地将字段标记为@Autowired不能按预期工作。代码将编译并且Web应用程序将启动 - 这意味着Spring成功地能够自动装载该字段,但是当servlet实际上被客户端代码命中时,它将产生NullPointerException - 就像有一个不同的,未被初始化的servlet副本被击中。

我在Web上找到了几种方法来实现这一点,一种方法是使用一个基本的servlet类来执行一些Spring逻辑,但这样做意味着每个GWT servlet都必须扩展这个基类。另一种方法是使用AspectJ和@Configurable Spring注释。这里涉及的配置非常少,只是神奇地工作。

我的问题是为什么不仅仅按照预期的方式自动装配该领域?什么是GWT,这会导致这种情况发生。

3 个答案:

答案 0 :(得分:4)

  

代码将编译,Web应用程序将启动 - 其中   意味着Spring成功地能够自动装载该领域

不一定。 Web容器可以在没有Spring帮助的情况下实例化servlet。您可能会遇到的问题:

  

但是当servlet实际上被客户端代码命中时,它会   产生一个NullPointerException - 就像有一个不同的,未初始化的   被击中的servlet的副本。

尝试覆盖Servlet的init():

@Override
public void init(ServletConfig config) throws ServletException {
    super.init(config);

    WebApplicationContextUtils.getWebApplicationContext(config.getServletContext())
        .getAutowireCapableBeanFactory().autowireBean(this);
}

答案 1 :(得分:1)

从客户端调用RPC服务时,"服务器端"查看被调用的URL和servlets映射将找到该类,将使实例和它将服务请求。这意味着如果您有@Autowired注释,或者您已在spring上下文中拥有RPC类的实例,则无关紧要。将创建新实例,并且不会知道"知道"关于春天。

我通过实现扩展RemoteServiceServlet并实现Controller(来自Spring MVC)和ServletContextAware的类来解决这个问题。 这样,您可以使用Spring MVC方法按URL映射每个RPC服务,例如:

<bean id="publicUrlMapping"
        class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
          <props>
            <prop key="/myFirstRpc">firstRpcServiceBeanRef</prop>
            <prop key="/mySecondRpc">secondRpcServiceRef</prop>
          </props>
        </property>
    </bean>

您还可以避免web.xml中每个RPC servlet的声明,映射是干净的,并且您有Spring注入。 您在web.xml中仅为org.springframework.web.servlet.DispatcherServlet声明了一个映射,它将提供所有RPC调用。

网上有几个例子,有关于GWT RPC和Spring MVC控制器集成的解释。

希望这会有所帮助。

答案 2 :(得分:0)

事实证明,至少在使用Spring时,有一种更简单的方法可以使用@Autowired并且它不涉及大量配置或基类。需要注意的是,您还必须使用AspectJ。以下是您的GWT servlet所需的内容:

@Configurable
public class MyGwtServiceImpl extends RemoteServiceServlet implements MyGwtService
{
  @Autowired
  private MyService service;

  // ...
}

在你的Spring配置中确保你也有:

   <!-- enable autowiring and configuration of non-spring managed classes, requires AspectJ -->
   <context:spring-configured/>

最后一点说明。如果您还在GWT应用程序(以及GWT servlet)中使用Spring安全性,则需要确保定义正确的模式以确保正确完成AspectJ编织(即,您同时获得@Secured注释处理和@Autowired处理)您将需要:

   <!-- turn on spring security for method annotations with @Secured(...) -->
   <!-- the aspectj mode is required because we autowire spring services into GWT servlets and this
        is also done via aspectj. a server 500 error will occur if this is changed or removed. -->
   <security:global-method-security secured-annotations="enabled" mode="aspectj"/>