为什么';在Spring work中,您不只是自动连接GWT servlet中的字段吗?

为什么';在Spring work中,您不只是自动连接GWT servlet中的字段吗?,spring,gwt,aspectj,autowired,configurable,Spring,Gwt,Aspectj,Autowired,Configurable,在GWT servlet中将字段简单地标记为@Autowired,并不能按预期工作。代码将被编译,web应用程序将启动—这意味着Spring能够成功地自动连接字段,但当servlet实际被客户端代码命中时,它将生成一个NullPointerException—就像被命中的servlet的另一个未初始化副本一样 我在web上找到了几种方法来实现这一点,一种是使用一个执行Spring逻辑的基本servlet类,但这样做意味着每个GWT servlet都必须扩展这个基本类。另一种方法是使用Aspect

在GWT servlet中将字段简单地标记为
@Autowired
,并不能按预期工作。代码将被编译,web应用程序将启动—这意味着Spring能够成功地自动连接字段,但当servlet实际被客户端代码命中时,它将生成一个
NullPointerException
—就像被命中的servlet的另一个未初始化副本一样

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

我的问题是,为什么不只是自动布线的领域只是工作的预期?GWT所做的什么导致了此故障

代码将被编译,web应用程序将启动-这是什么 意味着Spring能够成功地自动连接字段

不一定。web容器可以在没有Spring帮助的情况下实例化servlet。您可能会体验到:

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

尝试重写Servlet的init():


当从客户机调用RPC服务时,查看被调用URL和servlet映射的“服务器端”将找到类,创建实例并为请求提供服务。这意味着,如果您有
@Autowired
注释,或者您在spring上下文中已经有了RPC类的实例,这并不重要。新实例将被创建,它不会“知道”Spring

我通过实现一个类来解决这个问题,该类扩展了
RemoteServiceServlet
,并实现了
Controller
(来自SpringMVC)和
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>

firstRpcServiceBeanRef
第二个RPCServiceRef
您还可以避免对
web.xml
中的每个rpcservlet进行声明,映射是干净的,并且具有Spring注入。 在
org.springframework.web.servlet.DispatcherServlet
中,您只为
org.springframework.web.servlet.DispatcherServlet
声明一个映射,该映射将服务于所有RPC调用

web上有两个示例,解释了GWT RPC和Spring MVC控制器的集成


希望这会有所帮助。

事实证明,至少在使用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 security,则需要确保定义正确的模式,以确保正确完成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"/>


Ack!我很抱歉。我没有明确说明我们使用的不是SpringMVC,而是SpringWeb。考虑到我在网络上找到的信息,即一个控制器来控制所有的模式对我来说真的是错误的,因为我们会吸入整个框架组件,只使用一小部分。对我来说,Spring MVC的真正力量是能够创建任意数量的控制器,将类似功能的控制器组合在一起,将控制器方法与URI绑定在一起,并在逐个方法的基础上添加安全性—这一切都是自动发生的,只需很少的编码即可完成。我认为您将dispacher servlet与一个控制器混合在一起来管理它们。这个servlet映射给出了控制器使用的URL的一般定义,如/rpc/*。这就是想法。如果您已经包括了类似于Spring安全性的框架,那么您仍然有可能在方法级别上实现安全性。虽然您在回答的第一部分中在技术上是正确的,但是Spring默认情况下会根据需要处理自动连接的带注释的字段/方法,因此会验证它是否构建了一个可以匹配带注释项的bean。此外,在您回答的第二部分中,我在web上看到了这个解决方案,但需要注意的是:1)我需要创建一个父servlet类来扩展所有GWT servlet类,这是我一直希望避免的,2)此模式会干扰异常处理,并阻止在抛出异常时正确处理异常。请参见作者的评论:,以及他的解决方案——使用AspectJ。您不需要创建基类,每个servlet都可以为自己重写init():)True。然后,到处都会有冗余代码,它们只是尖叫着“基类…”-我想这就是你的观点。
   <!-- 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"/>