Liferay 门户:OSGI 模块化与 JSF 和 EJB-CDI 不使用 @Resource 注入/检索

乔治·琼佐夫

我目前正在使用 tomcat 开发 Liferay 7.1.2.ga3 CE,并且正在阅读官方文档中教程的 OSGI 部分。这一个:文档

我决定用最简单的项目试一试。我在我的 IntelliJ 想法中创建了一个 Liferay 工作区,并添加了一些在 turorial 中描述的组件。

问题是它要么不注入,要么注入但不检索依赖项,因为在这种情况下,在消费者中 _applicationServices 变量始终为空。

编辑: 我在这里的 Liferay 官方论坛上问了同样的问题: Liferay.org 中的问题

这是代码

api:

@ProviderType
public interface ApplicationServices {
    String getSearchFiltersForRegister(String registerCode);
}

提供者:

@Component(
    immediate = true,
    property = {
    },
    service = ApplicationServices.class
)
public class ApplicationServicesImpl implements ApplicationServices {
    @Override
    public String getSearchFiltersForRegister(String registerCode) {
        return "OSGI modularity made service";
    }
}

消费者:

@ManagedBean(name = "registerSearchBean")
@ViewScoped
@Component(
        immediate = true,
        property = {
                "osgi.command.scope=getSearchFiltersForRegister",
                "osgi.command.function=getSearchFiltersForRegister"
        },
        service = Object.class
)
public class RegisterSearchBean {

        public String message;

        @Reference
        private ApplicationServices _applicationServices;

        @PostConstruct
        public void initBean(){
                getSearchFiltersForRegister();
        }

        public void getSearchFiltersForRegister(){
                ApplicationServices applicationServices=_applicationServices;
                message=applicationServices.getSearchFiltersForRegister("asd");
        }

        public String getMessage() {
                return message;
        }

        public void setMessage(String message) {
                this.message = message;
        }
}

注意:我还尝试将 consumre 模块分离到不同的类中,并在此 bean 中使用它,但没有成功。

附加信息:

  • 该项目是一个 gradle LiferayWorkaspace。
  • Api 和服务模块是通过模块文件夹中的 Liferay 插件生成的。
  • JSF 模块是通过 maven 原型生成的,在“war”文件夹中提供 gradle 支持。
  • 依赖项被正确定义,并且都正确部署在 Liferay 服务器中。至少它看起来是这样......部署时不会出现缺少类的错误。

我做错了什么,为什么应用程序服务总是为空?

乔治·琼佐夫

Neil Griffin 在 liferay 论坛上广泛回答

嗨乔治,非常感谢您的联系。您提出了一个非常重要的问题,值得彻底回答。由于 JSF 是一种基于 Java EE 的技术,因此它期望该项目是一个 Web 应用程序存档 (WAR) 而不是 Java 存档 (JAR)。当 WAR 部署到 $LIFERAY_HOME/deploy 时,Liferay 会自动将 Java EE WAR 转换为 OSGi Web Application Bundle(WAemoticon。虽然 WAB 是一流的 OSGi 公民,但它们不通过用@Component 注释的类。更适合 WAB 的是 CDI,它通过扫描类路径来完成服务的部署时发现。因此,您粘贴的代码的难点在于:您正在结合 OSGi 声明式服务构建时发现(通过@Component)与CDI部署时发现(通过@ViewScoped)。这些需要以相互排斥的方式使用——换句话说,它们不能组合。这是令人鼓舞的消息——Liferay 7.1、7.2 和 7.3 在 $LIFERAY_HOME/modules 中随附了weld-osgi-bundle.jar 并且完全通过 OSGi CDI 集成支持 Portlet 3.0 的 CDI 要求。这意味着可以开发使用 JSR 330 @Inject 的 WAR,以便将来自 OSGi 服务注册表的服务注入 CDI bean。它还可以将 CDI bean 发布到 OSGi 服务注册中心。我最近在 Liferay DEVCON 2019 上发表了题为 Portlet 3.0 MVCBean 和 PortletMVC4Spring 的演讲,展示了 OSGi CDI 集成的前景。如果您有时间,我建议您观看演示文稿,因为它可以帮助您更好地了解它是如何工作的。但我很遗憾地说 JSF 不是 还不能充分利用这一点。我们仍在努力实现 JSR 378,这使得在 Liferay 中部署 JSF portlet 作为 Portlet 3.0“bean portlet”成为可能——这是启用所有 OSGi CDI 集成功能的部分。我们让它在 liferay-faces-bridge-impl.git 存储库的 5.x 分支中工作,但在 JSR 378 完成之前将无法削减生产版本。所以除非你想试验 5.x桥的版本,那么我建议您遵循我的 DEVCON 2016 演讲中的建议,标题为“以展望未来开发 WAB像 JSF 要求的那些 portlet。话虽如此,在 JAR 模块中使用 @Component(声明性服务)开发 OSGi 服务可能是个好主意。JAR 模块可以与 JSF portlet WAR 模块分开部署。这样,您应该能够通过 JSR 托管 bean 中的 ServiceTracker 从 OSGi 服务注册表获取服务(由 @Component 定义)。最终,一旦我们发布了 JSR 378,您将能够使用 JSR 330 @Inject 而不是 ServiceTracker,以便将您的 OSGi 服务注入您的 JSF 托管 bean(由 CDI 通过@javax.faces.view.ViewScoped 管理)。再次澄清,在未来,您可能希望使用 @ViewScoped 注释的 CDI 兼容版本,而不是打算与 @javax.faces.bean.ViewScoped 的 JSF Managed Bean Facility (MBF) 一起使用的版本. 亲切的问候,尼尔 JAR 模块可以与 JSF portlet WAR 模块分开部署。这样,您应该能够通过 JSR 托管 bean 中的 ServiceTracker 从 OSGi 服务注册表获取服务(由 @Component 定义)。最终,一旦我们发布了 JSR 378,您将能够使用 JSR 330 @Inject 而不是 ServiceTracker,以便将您的 OSGi 服务注入您的 JSF 托管 bean(由 CDI 通过@javax.faces.view.ViewScoped 管理)。再次澄清,在未来,您可能希望使用 @ViewScoped 注释的 CDI 兼容版本,而不是打算与 @javax.faces.bean.ViewScoped 的 JSF Managed Bean Facility (MBF) 一起使用的版本. 亲切的问候,尼尔 JAR 模块可以与 JSF portlet WAR 模块分开部署。这样,您应该能够通过 JSR 托管 bean 中的 ServiceTracker 从 OSGi 服务注册表获取服务(由 @Component 定义)。最终,一旦我们发布了 JSR 378,您将能够使用 JSR 330 @Inject 而不是 ServiceTracker,以便将您的 OSGi 服务注入您的 JSF 托管 bean(由 CDI 通过@javax.faces.view.ViewScoped 管理)。再次澄清,在未来,您可能希望使用 @ViewScoped 注释的 CDI 兼容版本,而不是打算与 @javax.faces.bean.ViewScoped 的 JSF Managed Bean Facility (MBF) 一起使用的版本. 亲切的问候,尼尔 您应该能够通过 JSR 托管 bean 中的 ServiceTracker 从 OSGi 服务注册表获取服务(由 @Component 定义)。最终,一旦我们发布了 JSR 378,您将能够使用 JSR 330 @Inject 而不是 ServiceTracker,以便将您的 OSGi 服务注入您的 JSF 托管 bean(由 CDI 通过@javax.faces.view.ViewScoped 管理)。再次澄清,在未来,您可能希望使用 @ViewScoped 注释的 CDI 兼容版本,而不是打算与 @javax.faces.bean.ViewScoped 的 JSF Managed Bean Facility (MBF) 一起使用的版本. 亲切的问候,尼尔 您应该能够通过 JSR 托管 bean 中的 ServiceTracker 从 OSGi 服务注册表获取服务(由 @Component 定义)。最终,一旦我们发布了 JSR 378,您将能够使用 JSR 330 @Inject 而不是 ServiceTracker,以便将您的 OSGi 服务注入您的 JSF 托管 bean(由 CDI 通过@javax.faces.view.ViewScoped 管理)。再次澄清,在未来,您可能希望使用 @ViewScoped 注释的 CDI 兼容版本,而不是打算与 @javax.faces.bean.ViewScoped 的 JSF Managed Bean Facility (MBF) 一起使用的版本. 亲切的问候,尼尔 faces.view.ViewScoped)。再次澄清,在未来,您可能希望使用 @ViewScoped 注释的 CDI 兼容版本,而不是打算与 @javax.faces.bean.ViewScoped 的 JSF Managed Bean Facility (MBF) 一起使用的版本. 亲切的问候,尼尔 faces.view.ViewScoped)。再次澄清,在未来,您可能希望使用 @ViewScoped 注释的 CDI 兼容版本,而不是打算与 @javax.faces.bean.ViewScoped 的 JSF Managed Bean Facility (MBF) 一起使用的版本. 亲切的问候,尼尔

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章