在GWT servlet中简单地将字段标记为@Autowired
不能按预期工作。代码将编译并且Web应用程序将启动 - 这意味着Spring成功地能够自动装载该字段,但是当servlet实际上被客户端代码命中时,它将产生NullPointerException
- 就像有一个不同的,未被初始化的servlet副本被击中。
我在Web上找到了几种方法来实现这一点,一种方法是使用一个基本的servlet类来执行一些Spring逻辑,但这样做意味着每个GWT servlet都必须扩展这个基类。另一种方法是使用AspectJ和@Configurable
Spring注释。这里涉及的配置非常少,只是神奇地工作。
我的问题是为什么不仅仅按照预期的方式自动装配该领域?什么是GWT,这会导致这种情况发生。
答案 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"/>