乐趣区

关于java:Spring认证中国教育管理中心Apache-Geode-的-Spring-数据教程二十四

原题目:Spring 认证中国教育管理中心 -Apache Geode 的 Spring 数据教程二十四(Spring 中国教育管理中心)

Apache Geode 的 Spring 数据教程二十四

  1. 函数执行的注解反对
    Spring Data for Apache Geode 包含正文反对以简化应用 Apache Geode 函数执行的工作。

在幕后,Apache Geode API 提供了实现和注册 Apache Geode 函数的类,这些函数部署在 Apache Geode 服务器上,而后能够由其余对等成员应用程序或从缓存客户端近程调用。

函数能够并行执行,散布在集群中的多个 Apache Geode 服务器中,应用 map-reduce 模式聚合后果并发回调用者。还能够将函数定位为在单个服务器或区域上运行。Apache Geode API 反对应用各种预约义范畴近程执行指标函数:区域、成员(组)、服务器等。近程函数的实现和执行,与任何 RPC 协定一样,须要一些样板代码。

Spring Data for Apache Geode 忠诚于 Spring 的外围价值主张,旨在暗藏近程函数执行的机制,让您专一于外围 POJO 编程和业务逻辑。为此,Apache Geode 的 Spring Data 引入了注解,以申明性地将 POJO 类的公共办法注册为 Apache Geode 函数,以及应用带正文的接口调用已注册函数(包含近程)的能力。

11.1. 施行与执行
有两个独自的问题须要解决:施行和执行。

第一个是函数实现(服务器端),它必须与 交互 FunctionContext 以拜访调用参数、ResultsSender 发送后果和其余执行上下文信息。Function 实现通常拜访缓存和区域,并 FunctionService 应用惟一 ID 注册。

调用函数的缓存客户端应用程序不依赖于实现。为了调用一个函数,应用程序实例化一个 Execution 提供函数 ID、调用参数和函数指标,它定义了它的范畴:区域、服务器、服务器、成员或成员。如果 Function 产生后果,调用者应用 a ResultCollector 来聚合并获取执行后果。在某些状况下,须要自定义 ResultCollector 实现,并且能够应用 Execution.

‘Client’ 和 ‘Server’ 在函数执行的上下文中应用,这可能与 Apache Geode 的客户端 – 服务器拓扑中的客户端和服务器具备不同的含意。尽管应用程序应用 ClientCache 实例调用集群中一个或多个 Apache Geode 服务器上的函数是很常见的,但也能够在对等 (P2P) 配置中执行函数,其中应用程序是成员托管对等 Cache 实例的集群。请记住,对等成员缓存应用程序受作为集群对等成员的所有束缚的束缚。

11.2. 实现一个性能
应用 Apache Geode API,它 FunctionContext 提供了一个运行时调用上下文,其中包含客户端的调用参数和 ResultSender 将后果发送回客户端的实现。此外,如果 Function 在 Region 上执行,FunctionContext 则实际上是 的一个实例 RegionFunctionContext,它提供附加信息,例如调用 Function 的指标 Region Execution、与关联的任何过滤器(一组特定键),等等在。如果 Region 是 PARTITIONRegion,则 Function 应该应用 PartitionRegionHelper 来提取本地数据集。

通过应用 Spring,您能够编写一个简略的 POJO 并应用 Spring 容器将一个或多个 POJO 的公共办法绑定到一个函数。打算用作函数的 POJO 办法的签名通常必须合乎客户端的执行参数。然而在一个 Region 执行的状况下,也可能会提供 Region 数据(如果 Region 是 PARTITIONRegion 的话,大略数据是保留在本地分区的)。

此外,该函数可能须要利用的过滤器(如果有)。这表明客户端和服务器共享调用参数的合同,但办法签名可能蕴含附加参数以传递 FunctionContext. 一种可能性是客户端和服务器共享一个公共接口,但这不是严格要求的。惟一的限度是办法签名包含与解析附加参数后调用函数雷同的调用参数序列。

例如,假如客户端提供 aString 和 anint 作为调用参数。这些 FunctionContext 以数组的模式提供,如以下示例所示:

Object[] args = new Object[] {“test”, 123};

Spring 容器应该可能绑定到任何相似于以下的办法签名(临时疏忽返回类型):

public Object method1(String s1, int i2) {…}
public Object method2(Map<?, ?> data, String s1, int i2) {…}
public Object method3(String s1, Map<?, ?> data, int i2) {…}
public Object method4(String s1, Map<?, ?> data, Set<?> filter, int i2) {…}
public void method4(String s1, Set<?> filter, int i2, Region<?,?> data) {…}
public void method5(String s1, ResultSender rs, int i2) {…}
public void method6(FunctionContest context) {…}
个别规定是,一旦解析了任何附加参数(即区域数据和过滤器),其余参数必须在程序和类型上与预期的 Function 办法参数齐全对应。该办法的返回类型必须是空的或可序列化类型(作为 java.io.Serializable,DataSerializable 或 PdxSerializable)。后者也是调用参数的要求。

Region 数据通常应定义为 Map, 以不便单元测试,但如有必要,也能够是 Region 类型。如后面的示例所示,如果您须要管制如何将后果返回给客户端,则传递 FunctionContext 自身或传递也是无效 ResultSender 的。

11.2.1. 函数实现的注解
以下示例展现了如何应用 SDG 的函数正文将 POJO 办法公开为 Apache Geode 函数:

@Component
public class ApplicationFunctions {

@GemfireFunction
public String function1(String value, @RegionData Map<?, ?> data, int i2) {…}

@GemfireFunction(id = “myFunction”, batchSize=100, HA=true, optimizedForWrite=true)
public List<String> function2(String value, @RegionData Map<?, ?> data, int i2, @Filter Set<?> keys) {…}

@GemfireFunction(hasResult=true)
public void functionWithContext(FunctionContext functionContext) {…}

}
请留神,类自身必须注册为 Spring bean,并且每个 Apache Geode 函数都应用 @GemfireFunction. 在后面的例子中,应用了 Spring 的 @Component 注解,然而您能够应用 Spring 反对的任何办法(例如 XML 配置或应用 Spring Boot 时应用 Java 配置类)来注册 bean。这让 Spring 容器能够创立此类的实例并将其包装在 PojoFunctionWrapper. Spring 为每个用 正文的办法创立一个包装器实例 @GemfireFunction。每个包装器实例共享雷同的指标对象实例以调用相应的办法。

POJO Function 类是 Spring bean 的事实可能提供其余益处。因为它 ApplicationContext 与 Apache Geode 组件(例如缓存和区域)共享,因而能够在必要时将它们注入到类中。

Spring 创立包装类并将函数注册到 Apache Geode 的 FunctionService. 用于注册每个函数的函数 ID 必须是惟一的。通过应用约定,它默认为简略(非限定)办法名称。能够应用正文的 id 属性显式定义名称 @GemfireFunction。

该 @GemfireFunction 注解还提供了其余配置属性:HAand optimizedForWrite,它们对应于 Apache GeodeFunction 接口定义的属性。

如果 POJO Function 办法的返回类型为 void,则该 hasResult 属性会主动设置为 false。否则,如果该办法返回一个值,则 hasResult 属性设置为 true。即便对于 void 办法返回类型,也能够将 GemfireFunction 注解的 hasResult 属性设置 true 为笼罩此约定,如 functionWithContext 后面显示的办法所示。据揣测,目标是您将 ResultSender 间接应用将后果发送给调用者。

最初,GemfireFunction 注解反对 requiredPermissions 属性,该属性指定执行函数所需的权限。默认状况下,所有性能都须要 DATA:WRITE 权限。该属性承受一个字符串数组,容许您依据应用程序和 / 或性能 UC 的要求批改权限。每个资源权限应采纳以下格局:<RESOURCE>:<OPERATION>:[Target]:[Key].

RESOURCE 能够是 {data-store-javadoc]
/org/apache/geode/security/ResourcePermission.Resource.html[ResourcePermission.Resource] 枚举值之一。OPERATION 能够是 {data-store-javadoc}/org/apache/geode/security/ResourcePermission.Operation.html[ResourcePermission.Operation] 枚举值之一。可选地,Target 能够是区域的名称或 {data-store-javadoc}/org/apache/geode/security/ResourcePermission.Target.html[ResourcePermission.Target] 枚举值中的 1 个。最初,如果指定,Key 则可选地是区域中的无效密钥 Target。

所述 PojoFunctionWrapper 用具的 Apache 的 Geode 的 Function 界面,联合办法的参数,并调用在其指标办法 execute()的办法。它还通过应用 将办法的返回值发送回调用者 ResultSender。

11.2.2. 批处理后果
如果返回类型是数组或 Collection,则必须思考如何返回后果。默认状况下,PojoFunctionWrapper 返回整个数组或 Collection 一次。如果数组中的元素数量 或 Collection 十分大,则可能会导致性能损失。要将无效负载划分为更小、更易于治理的块,您能够设置 batchSize 属性,如 function2 后面所示的 中所示。

如果您须要更多地管制 ResultSender,特地是如果办法自身会应用太多内存来创立 Collection,您能够传入 ResultSender 或通过 拜访它 FunctionContext 并间接在办法中应用它以将后果发送回调用者。

11.2.3. 启用正文解决
依据 Spring 规范,您必须显式激活注解的注解解决 @GemfireFunction。以下示例应用 XML 激活正文解决:

<gfe:annotation-driven/>
以下示例通过正文 Java 配置类来激活正文解决:

@Configuration
@EnableGemfireFunctions
class ApplicationConfiguration {…}
11.3. 执行函数
调用近程性能需要的办法,以提供对性能的 ID,调用自变量,执行对象(onRegion,onServers,onServer,onMember,或 onMembers)和(任选地)一个滤波器汇合。通过应用 Spring Data for Apache Geode,您只需定义一个注解反对的接口。Spring 为接口创立一个动静代理,它应用 FunctionService 来创立 Execution,调用 Execution,并且(如果须要)将后果强制为定义的返回类型。这种技术相似于 Spring Data for Apache Geode 的 Repository 扩大的工作形式。因而,一些配置和概念应该是相熟的。

通常,单个接口定义映射到多个 Function 执行,一个对应于接口中定义的每个办法。

11.3.1. 函数执行注解
为了反对客户端性能执行,提供了上面的性能 SDG 正文:@OnRegion,@OnServer,@OnServers,@OnMember,和 @OnMembers。这些正文对应于 Execution Apache GeodeFunctionService 类提供的实现。

每个正文都公开了适当的属性。这些正文还提供了一个可选 resultCollector 属性,其值是实现 ResultCollector 用于执行的接口的 Spring bean 的名称。

代理接口将所有申明的办法绑定到雷同的执行配置。尽管冀望繁多办法接口是通用的,但接口中的所有办法都由雷同的代理实例反对,因而都共享雷同的配置。

以下清单显示了一些示例:

@OnRegion(region=”SomeRegion”, resultCollector=”myCollector”)
public interface FunctionExecution {

@FunctionId("function1")
String doIt(String s1, int i2);

String getString(Object arg1, @Filter Set<Object> keys);

}
默认状况下,函数 ID 是简略(非限定)办法名称。该 @FunctionId 正文可被用于此调用绑定到一个不同的性能 ID。

11.3.2. 启用正文解决
客户端应用 Spring 的类门路组件扫描性能来发现带正文的接口。要在 XML 中启用函数执行正文解决,请在 XML 配置中插入以下元素:

<gfe-data:function-executions base-package=”org.example.myapp.gemfire.functions”/>
该 function-executions 元素在 gfe-dataXML 命名空间中提供。base-package 须要该属性以防止扫描整个类门路。能够提供额定的过滤器,如 Spring 参考文档中所述。

或者,您能够按如下形式正文 Java 配置类:

@EnableGemfireFunctionExecutions(basePackages = “org.example.myapp.gemfire.functions”)
11.4. 程序化函数执行
应用上一节中定义的函数执行正文接口,只需将您的接口主动连贯到将调用函数的应用程序 bean 中:

@Component
public class MyApplication {

@Autowired
FunctionExecution functionExecution;

public void doSomething() {functionExecution.doIt("hello", 123);
}

}
或者,您能够间接应用函数执行模板。在以下示例中,
GemfireOnRegionFunctionTemplate 创立了一个 onRegionFunction Execution:

示例 19. 应用
GemfireOnRegionFunctionTemplate

Set<?, ?> myFilter = getFilter();
Region<?, ?> myRegion = getRegion();
GemfireOnRegionOperations template = new GemfireOnRegionFunctionTemplate(myRegion);
String result = template.executeAndExtract(“someFunction”, myFilter, “hello”, “world”, 1234);
在外部,FunctionExecutions 总是返回一个 List. executeAndExtract 假设 List 蕴含后果的单例并尝试将该值强制转换为申请的类型。还有一种 execute 办法能够按 List 原样返回。第一个参数是函数 ID。过滤器参数是可选的。其余参数是可变参数 List。

11.5. 应用 PDX 执行函数
将 Spring Data for Apache Geode 的 Function annotation 反对与 Apache Geode 的 PDX Serialization 联合应用时,须要记住一些逻辑上的事件。

正如本节后面所解释的,作为示例,您通常应该应用应用 Spring Data 正文的 POJO 类来定义 Apache Geode Functions,用于 Apache Geode Function annotations,如下所示:

public class OrderFunctions {

@GemfireFunction(…)
Order process(@RegionData data, Order order, OrderSource orderSourceEnum, Integer count) {…}

}
的 Integer 类型化的 count 参数是任意的,因为是拆散 Order 类和 OrderSource 枚举,这可能是合乎逻辑的联合。然而,以这种形式设置参数是为了演示 PDX 上下文中函数执行的问题。
您的 Order 类和 OrderSource 枚举可能定义如下:

public class Order … {

private Long orderNumber;
private LocalDateTime orderDateTime;
private Customer customer;
private List<Item> items


}

public enum OrderSource {
ONLINE,
PHONE,
POINT_OF_SALE

}
当然,你能够定义一个 FunctionExecution 接口来调用 ’process’Apache Geode 服务器 Function,如下:

@OnServer
public interface OrderProcessingFunctions {
Order process(Order order, OrderSource orderSourceEnum, Integer count);
}
显然,这个 process(..) Order 函数是从客户端用一个 ClientCache 实例(即 <gfe:client-cache/>)调用的。这意味着函数参数也必须是可序列化的。@OnMember(s)在集群中的对等点之间调用点对点成员函数(例如)时也是如此。任何模式的 都 distribution 要求在客户端和服务器(或对等方)之间传输的数据被序列化。

当初,如果您已将 Apache Geode 配置为应用 PDX 进行序列化(例如,而不是 Java 序列化),您还 pdx-read-serialized 能够 true 在 Apache Geode 服务器的配置中将该属性设置为,如下所示:

<gfe:cache pdx-read-serialized=”true”/>
或者,您能够将 pdx-read-serialized 属性设置 true 为 Apache Geode 缓存客户端应用程序,如下所示:

<gfe:client-cache pdx-read-serialized=”true”/>
这样做会导致从缓存(即区域)读取的所有值以及在客户端和服务器(或对等方)之间传递的信息放弃序列化模式,包含但不限于函数参数。

Apache Geode 仅序列化您通过应用 Apache Geode’
sReflectionBasedAutoSerializer 或通过应用“自定义”Apache Geode 专门(和举荐)专门配置(注册)的应用程序域对象类型 PdxSerializer。如果您应用 Spring Data for Apache Geode 的 Repository 扩大,您甚至可能须要思考应用 Spring Data for Apache Geode’s MappingPdxSerializer,它应用实体的映射元数据来确定序列化到 PDX 实例的应用程序域对象中的数据。

然而,不太显著的是 Apache Geode 会主动解决 JavaEnum 类型,而不论它们是否被显式配置(即
ReflectionBasedAutoSerializer 应用 regex 模式和 classes 参数注册,或者由“自定义”Apache Geode 解决 PdxSerializer),只管 Java 枚举实现了 java.io.Serializable.

因而,当您在注册了 Apache Geode Functions(包含 Spring Data for Apache Geode Function-annotated POJO classes)的 Apache Geode 服务器上设置 pdx-read-serialized 为时,您 true 在调用 Function 时可能会遇到令人诧异的行为 Execution。

您能够在调用函数时传递以下参数:

orderProcessingFunctions.process(new Order(123, customer, LocalDateTime.now(), items), OrderSource.ONLINE, 400);
然而,服务器上的 Apache Geode Function 取得以下信息:

process(regionData, order:PdxInstance, :PdxInstanceEnum, 400);
在 Order 与 OrderSource 已传递给函数的 PDX 实例。同样,这一切都是因为 pdx-read-serialized 设置为 true,这在 Apache Geode 服务器与多个不同客户端交互的状况下可能是必要的(例如,Java 客户端和本机客户端的组合,如 C/C++、C# 等).

这与 Spring Data for Apache Geode 的强类型函数正文 POJO 类办法签名南辕北辙,您能够正当地冀望应用程序域对象类型,而不是 PDX 序列化实例。

因而,Apache Geode 的 Spring Data 包含加强的 Function 反对,以主动将 PDX 类型的办法参数转换为由 Function 办法的签名(参数类型)定义的所需应用程序域对象类型。

然而,这也要求您 PdxSerializer 在注册和应用 Spring Data for Apache Geode Function-annotated POJOs 的 Apache Geode 服务器上显式注册 Apache Geode,如以下示例所示:

<bean id=”customPdxSerializer” class=”x.y.z.gemfire.serialization.pdx.MyCustomPdxSerializer”/>

<gfe:cache pdx-serializer-ref=”customPdxSerializeer” pdx-read-serialized=”true”/>
或者,
ReflectionBasedAutoSerializer 为了不便起见,您能够应用 Apache Geode。当然,咱们建议您在可能的状况下应用自定义 PdxSerializer 来放弃对序列化策略的细粒度管制。

最初,如果您将 Function 参数视为一般性或 Apache Geode 的 PDX 类型之一,则 Spring Data for Apache Geode 会留神不要转换您的 Function 参数,如下所示:

@GemfireFunction
public Object genericFunction(String value, Object domainObject, PdxInstanceEnum pdxEnum) {
// …
}
Spring Data for Apache Geode 将 PDX 类型的数据转换为相应的应用程序域类型,当且仅当相应的应用程序域类型在类门路上并且 Function-annotated POJO 办法须要它时。

无关自定义的、组合的特定于应用程序的 Apache GeodePdxSerializers 以及基于办法签名的适当 POJO 函数参数类型解决的一个很好的示例。

退出移动版