我有一个包含很少弹簧portlet的Web应用程序。每个portlet都有一个带有声明控制器的xml,但控制器使用的服务放在applicationContext.xml中。我知道为每个portlet创建一个spring应用程序上下文(来自自己的xml文件),并且每个上下文都具有从applicationContext.xml创建的spring应用程序上下文作为root上下文。也就是说,applicationContext.xml中声明的所有bean对所有portlet都是通用的。
让我们举个例子:
portlet的
controller ExampleController.java :
package example.controller;
@Controller
@RequestMapping(value = "VIEW")
public class NavigareController {
@Autowired
private ExampleService es;
...
}
的applicationContext.xml :
...
<context:component-scan base-package="example.service />
...
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);
...
上面的代码,在第一种情况下(当服务器在应用程序内部启动时)返回not null parent,但在第二种情况下(当重新部署应用程序时)它返回null父项。在PortletApplicationContextUtils.getWebApplicationContext(getPortletContext())中有以下代码:
Object attr = pc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
因此,在第一种情况下,此属性位于portlet上下文中,但在第二种情况下,它不在portlet上下文中。问题很明显,在null parent中找不到exampleService bean。
问题是:热部署过程中是否存在任何错误?。请帮我!!!
答案 0 :(得分:2)
你的Liferay版本是什么?如果它是6.1.1那么这是一个已知问题
http://issues.liferay.com/browse/LPS-29103
如果您只需要部署一次portlet - 按照故障单中的建议手动更改web.xml中侦听器的顺序。
如果您需要重新部署portlet(用于开发),那么之前的解决方案非常耗时,最简单的方法是从6.2.0分支向后移植修复程序。