1

我有一个带有几个 spring portlet 的 Web 应用程序。每个 portlet 都有一个带有声明控制器的 xml,但控制器使用的服务放在 applicationContext.xml 中。我知道每个portlet 都会创建一个spring 应用程序上下文(来自自己的xml 文件),并且每个上下文都具有从applicationContext.xml 创建的spring 应用程序上下文作为根上下文。也就是说,在 applicationContext.xml 中声明的所有 bean 对于所有 portlet 都是通用的。

所以让我们举个例子:

portlet example-portlet.xml 的xml 文件: ... ...

控制器ExampleController.java

package example.controller;
@Controller
@RequestMapping(value = "VIEW")
public class NavigareController {

@Autowired
private ExampleService es;
...
}

应用上下文.xml

...
<context:component-scan base-package="example.service />
...

服务ExampleServiceImpl.java

package example.service;
@Service
public class ExampleServiceImpl implements ExampleService {
...
}

当服务器启动其中的应用程序时,应用程序启动并且一切正常。重新部署应用程序时,出现错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exampleController'...
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private example.service.ExampleService...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [example.service.ExampleService]...

结果 portlet 没有启动。

我已经调试了lifery的源代码,我发现了以下代码:

package org.springframework.web.portlet
...
public abstract class FrameworkPortlet extends GenericPortletBean
implements ApplicationListener<ContextRefreshedEvent> {
...
protected ApplicationContext initPortletApplicationContext() {
ApplicationContext parent = PortletApplicationContextUtils.getWebApplicationContext(getPortletContext());
ApplicationContext pac = createPortletApplicationContext(parent);
...

上面的代码,在第一种情况下(当服务器在内部启动应用程序时)返回不为 null 的父级,但在第二种情况下(当重新部署应用程序时)它返回一个 null 父级。在 PortletApplicationContextUtils.getWebApplicationContext(getPortletContext()) 中有以下代码:

Object attr = pc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

因此,在第一种情况下,该属性在 portlet 上下文中,但在第二种情况下,它不在 portlet 上下文中。问题很清楚,在 null parent 中找不到 exampleService bean。

问题是:热部署过程中是否有任何错误?. 请帮我!!!

4

1 回答 1

2

你的 Liferay 版本是什么?如果是 6.1.1,那么这是一个已知问题

http://issues.liferay.com/browse/LPS-29103

如果您只需要部署一次 portlet - 按照票证中的建议手动更改 web.xml 中侦听器的顺序。

如果您需要大量重新部署 portlet(用于开发),那么以前的解决方案非常耗时,最简单的方法是从 6.2.0 分支向后移植修复程序。

于 2012-10-02T05:48:08.913 回答