我们将创建自定义捆绑包并将其部署到AEM中。
在这样做的同时,我们将学习OSGi组件和OSGi服务的概念。
软件模块化
在现代,可以将复杂的软件视为各种模块或组件的集合。这些模块通常彼此独立,并且在一个模块中进行修改不会影响其他模块。
这些模块通过API相互交互。API被定义为可以从其他组件使用的一组类和方法。
如果一个模块使用另一个模块中的API,则它对另一个模块具有依赖性,即,它要求另一个模块存在并且可以正常工作。
其他组件使用的模块应保持其API稳定。这样可以避免更改影响其他模块。但是它应该可以自由更改其内部实现。
什么是OSGi?
OSGi代表开放服务网关计划。它是用于开发和部署模块化软件程序和库的Java框架。
OSGi有两个部分。
第一部分是称为捆绑的模块化组件的规范,通常称为插件。该规范定义了捆绑软件生命周期的基础架构,并确定了捆绑软件将如何交互。
OSGi的第二部分是Java虚拟机(JVM)级别的服务注册表,捆绑包可用于在面向服务的体系结构(SOA)中发布,发现和绑定到服务。
组件和服务可以动态安装,激活,停用,更新和卸载。
OSGi规范有几个实现中,例如,Equinox,Knopflerfish, 和Apache Felix。AEM使用Apache Felix实现。捆绑软件是模块化的最小单元,这意味着在OSGi中,软件组件是捆绑软件。
在AEM中,除了开箱即用的捆绑包之外,我们还可以非常轻松地安装自定义捆绑包。
创建捆绑
现在,我们将创建一个具有OSGi服务的OSGi捆绑包,该服务可使用HTTP GET请求从URL- https://jsonplaceholder.typicode.com/todos/.读取JSON数据。以下是创建OSGi捆绑包的步骤-
- 在IDEA中创建一个AEM多模块项目。创建ReadJsonService 接口服务在包 com.adobe.aem.guides.wknd.core.services;下。
package com.adobe.aem.guides.wknd.core.services;
/**
* 服务接口.
*/
public interface ReadJsonService {
/**
* @return JSON String
*/
public String getData();
}
- 现在需要创建ReadJsonService 接口的一个实现类ReadJsonDataImpl在com.adobe.aem.guides.wknd.core.services.impl;
package com.adobe.aem.guides.wknd.core.services.impl;
import com.adobe.aem.guides.wknd.core.constants.AppConstants;
import com.adobe.aem.guides.wknd.core.services.ReadJsonService;
import com.adobe.aem.guides.wknd.core.utils.Network;
import org.osgi.service.component.annotations.Component;
/**
* @author kevin.
* @Title: rhtj.
* @Package com.adobe.aem.guides.wknd.core.services.impl.
* @Description: 服务接口实现类..
* @date 2020/3/3011:11 上午.
*/
@Component(immediate = true, service = ReadJsonService.class)
public class ReadJsonDataImpl implements ReadJsonService {
/**
* @return JSON String
*/
@Override
public String getData() {
return Network.readJson(AppConstants.URL);
}
}
- 现在创建用于存储项目常量的常量类和用于HTTP请求的Network类
package com.adobe.aem.guides.wknd.core.constants;
/**
* @author kevin.
* @Title: rhtj.
* @Package com.adobe.aem.guides.wknd.core.
* @Description: 常量类..
* @date 2020/3/3011:14 上午.
*/
public class AppConstants {
/**假数据服务.**/
public static final String URL = "https://jsonplaceholder.typicode.com/todos/";
}
package com.adobe.aem.guides.wknd.core.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
/**
* @author kevin.
* @Title: rhtj.
* @Package com.adobe.aem.guides.wknd.core.utils.
* @Description: 网络相关的调用类.
* @date 2020/3/3011:16 上午.
*/
public class Network {
private static final String USER_AGENT = "Mozilla/5.0";
public static String readJson(String url) {
try {
URL requestUrl = new URL(url);
HttpsURLConnection connection = (HttpsURLConnection) requestUrl.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = connection.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
- 让我们了解这段代码。如果您仔细阅读ReadJsonServiceImpl.java,将看到@Component注解。此注解表示该类是AEM中的组件,属性 service = ReadJsonService.class 表示这是通过ReadJsonService接口公开的服务。
OSGi组件和服务
服务是在OSGi服务注册表中注册的对象,可以使用其接口名称进行查找。唯一的先决条件是服务应实现某些接口。例如,我可以在java.lang.Runnable接口下注册一个可运行对象,客户端可以使用该接口名称进行查找。
“组件”往往是对象的生命周期,通常由诸如声明性服务(DS),Blueprint或iPOJO之类的组件框架来管理。
一个组件可以具有以下任何一项功能,这些功能可以组合使用或单独使用:
- 组件可以启动和停止;被视为“活动”组件。不需要启动或停止的组件称为被动组件
- 组件可以将自身发布为OSGi服务。
- 组件可以绑定或使用OSGi服务。
- 通常,使用组件框架是使用OSGi服务的最简单方法,因为该框架将管理与您要使用的服务的绑定。例如,您可以说您的组件“依赖”特定服务,在这种情况下,仅当该服务可用时才创建并激活该组件,并且当该服务不可用时也将销毁该组件。
- Java代码完成后,我们现在可以使用IDEA和maven部署代码。
- 现在转到AEM实例,在CRXDE中,您应该在/ apps文件夹下看到您的项目。
- 右键单击/apps/wknd/components/content,然后创建组件…。
- 在对话框中,填写以下截图中所示的值
- 单击下一步,然后单击确定。
- 转到 /apps/wknd/components/content/sampleComponent并打开sampleComponent.jsp文件,然后添加以下代码并保存。
<%@include file="/libs/foundation/global.jsp"%>
<%
com.adobe.aem.guides.wknd.core.services.ReadJsonService service = sling.getService(com.adobe.aem.guides.wknd.core.services.ReadJsonService.class);
String result = service.getData();
%>
<h1>RESPONSE</h1>
<h3>RESPONSE: <%=result%></h3>
- 在页面上添加示例组件,您应该能够看到该页面上返回的JSON字符串,如下所示
[
{“ userId”:1,“ id”:1,“ title”:“ delectus aut autem”,“ completed”:false},
{“ userId”:1,“ id”:2,“ title”:“ quis ut nam facilis et officia qui”,“ completed”:false},
{“ userId”:1,“ id”:3,“ title”:“ fugiat veniam minus”,“ completed”:false},
{“ userId”:1,“ id”:4,“ title”:“ et porro tempora”,“ completed”:true},…
]
tips:
- 若在组件正常的情况下,你在页面上找不到你的组件,你可以直接通过代码进行引用组件,示例如下图。
- 若在组件正常的情况下,你在页面上找不到你的组件,可以将组件分组调整为可见的组件分组,示例如下图。
- 您可以分别在http://localhost:4502/system/console/components/ 和 http://localhost:4502/system/console/services/上检查组件和服务是否已安装在AEM服务器中 。