【问题标题】:Why does <context:component-scan> not resolve Spring beans in an OSGi fragment bundle?为什么 <context:component-scan> 不能解析 OSGi 片段包中的 Spring bean?
【发布时间】:2012-04-13 22:04:55
【问题描述】:

我正在构建一个 Spring 3、JSF 2、OSGi (Virgo Tomcat 3.5.0.M03) 应用程序。

目前我有一个主机 web 包和一个片段包。 片段包将一些.xhtml JSF 页面(facelets)添加到主机。片段中的 JSF 页面有自己的 UI 控制器(Spring bean 使用 action 属性绑定到 commandButton)。

我已经在我的主机(Web 应用程序)捆绑包的 applicationContext.xml 中使用 &lt;context:component-scan base-package="my.scan.package" /&gt; 配置了 Spring bean。

现在虽然context:component-scan 适用于主机包(即发现充当 UI 控制器的 Spring bean),但在片段包的情况下它会失败:

javax.el.PropertyNotFoundException: /flow-deployer-db.xhtml @20,50 action="#{uiControllerDb.deployFlow()}": Target Unreachable, identifier 'uiControllerDb' resolved to null
    com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:107)

因此,尽管片段应该与其宿主位于同一类路径中,并且 ui 控制器类在片段中声明如下:

package my.scan.package;
...
@Component("uiControllerDb")
public class UIControllerDb implements Serializable {

无法解析片段中的 bean(在主机包中工作时):

    <h:commandButton id="deployFlow" value="Deploy Flow" type="submit"
         action="#{uiControllerDb.deployFlow()}" />

从主机包的MANIFEST.MF中提取

...
Bundle-SymbolicName: web.host
Bundle-Version: 4.0.0.alpha
Require-Bundle: org.glassfish.com.sun.faces
Import-Package: javax.naming,javax.sql
Import-Bundle: org.eclipse.virgo.web.dm;version="[3.0.2.RELEASE,4)"
Import-Library: org.springframework.spring;version="[3.0,3.1.1)"
Bundle-Name: Web Host bundle
Web-ContextPath: /webHost

从片段 MANIFEST.MF 中提取:

Bundle-SymbolicName: my.fragment.bundle
Bundle-Version: 4.0.0.alpha
Import-Library: org.springframework.spring;version="[3.0,3.1.1)"
Fragment-Host: web.host;bundle-version=4.0.0.alpha

如何让 JSF 解析片段中的 Spring bean? 任何指针表示赞赏。谢谢。

faces-config.xml:

<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">

<application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

</faces-config>

web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">

<context-param>
    <param-name>contextClass</param-name>
    <param-value>org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value>
</context-param>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>

</web-app>

【问题讨论】:

  • 好的,我找到了答案。由于 Spring 上下文是在应用程序启动时创建的,因此使用 Spring bean 添加片段不会更新上下文。弹跳容器(Virgo)似乎解决了这个问题——片段中带注释的 bean 成为统一主机片段上下文的一部分。只有我期望在部署片段时会发生这种情况,因为 Virgo 在部署片段时无论如何都会刷新(停止和重新启动)主机包。
  • 请将其发布为答案并将其标记为正确答案,其他寻找此问题答案的用户会发现它很有用! meta.stackexchange.com/questions/12513/…
  • @Gabber:会的,谢谢。 (刚刚尝试过,显然我必须等待 8 小时——仍然声名狼藉 :)

标签: spring osgi


【解决方案1】:

好的,我找到了答案。 Spring 上下文是在应用程序启动时创建的 - 因此使用 Spring bean 添加片段不会自动更新上下文。 弹跳容器(Virgo)似乎解决了这个问题——片段中带注释的 bean 成为统一主机片段上下文的一部分。

问题是,我预计这会在部署 Fragment 时发生,因为 Virgo 在部署 Fragment 时无论如何都会刷新(停止和重新启动)主机包。

【讨论】:

    猜你喜欢
    • 2011-10-04
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多