我有一个带有几个 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。
问题是:热部署过程中是否有任何错误?. 请帮我!!!