乐趣区

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

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

Apache Geode 的 Spring 数据教程二十二
9.2.1. 按区域类型的实体映射
除了 @Region 正文,为 Apache 的 Geode 春数据也抵赖特定类型的区域映射正文:@ClientRegion,@LocalRegion,@PartitionRegion,和 @ReplicateRegion。

在性能上,这些正文的解决形式 @Region 与 SDG 映射基础设施中的通用正文完全相同。然而,这些额定的映射注解在 Spring Data for Apache Geode 的注解配置模型中很有用。联合 @
EnableEntityDefinedRegionsSpring@Configuration 注解类上的配置注解,能够在本地缓存中生成 Region,无论利用是 client 还是 peer。

这些正文让您能够更具体地理解您的应用程序实体类应该映射到什么类型的 Region,并且还会影响 Region 的数据管理策略(例如,分区 — 也称为分片 — 与复制数据)。

将这些特定于类型的区域映射正文与 SDG 正文配置模型联合应用,您不用在配置中明确定义这些区域。

9.3. 存储库映射
除了应用 @Region 实体类上的 @Region 注解指定存储实体的 Region 之外,您还能够在实体的 Repository 接口上指定注解。无关更多详细信息,请参阅 Apache Geode 存储库的 Spring 数据。

然而,假如您想 Person 在多个 Apache Geode 区域(例如,People 和 Customers)中存储一条记录。而后你能够定义你相应的 Repository 接口扩大如下:

@Region(“People”)
public interface PersonRepository extends GemfireRepository<Person, String> {

}

@Region(“Customers”)
public interface CustomerRepository extends GemfireRepository<Person, String> {

}
而后,独自应用每个存储库,您能够将实体存储在多个 Apache Geode 区域中,如以下示例所示:

@Service
class CustomerService {

CustomerRepository customerRepo;

PersonRepository personRepo;

Customer update(Customer customer) {

customerRepo.save(customer);
personRepo.save(customer);
return customer;

}
您甚至能够将 update 服务办法包装在 Spring 治理的事务中,作为本地缓存事务或全局事务。

9.4.MappingPdxSerializer
Spring Data for Apache Geode 提供了一个 PdxSerializer 名为的自定义实现 MappingPdxSerializer,它应用 Spring Data 映射元数据来自定义实体序列化。

序列化程序还容许您应用 Spring DataEntityInstantiator 形象自定义实体实例化。默认状况下,序列化程序应用
ReflectionEntityInstantiator,它应用映射实体的持久性构造函数。持久性构造函数要么是默认构造函数,要么是独自申明的构造函数,要么是显式用 @PersistenceConstructor.

为了为结构函数参数提供参数,序列化器从提供的 中读取具备命名结构函数参数的字段,应用 Spring 的 @Value 注解 明确标识 PdxReader,如上面的示例所示:

示例 4. 应用 @Value 实体结构函数参数

public class Person {

public Person(@Value(“#root.thing”) String firstName, @Value(“bean”) String lastName) {

}
}
以这种形式正文的实体类具备从 读取 PdxReader 并作为结构函数参数的参数值传递的“事物”字段 firstname。的值 lastName 是一个名为“bean”的 Spring bean。

除了 Apache Geode 提供的自定义实例化逻辑和策略之外 EntityInstantiators,MappingPdxSerializer 它还提供了远远超出 Apache Geode 本身的性能
ReflectionBasedAutoSerializer。

尽管 Apache
GeodeReflectionBasedAutoSerializer 不便地应用 Java 反射来填充实体并应用正则表达式来辨认序列化器应该解决(序列化和反序列化)的类型,但与 不同 MappingPdxSerializer,它不能执行以下操作:

为 PdxSerializer 每个实体字段或属性名称和类型注册自定义对象。
不便地辨认 ID 属性。
主动解决只读属性。
主动解决瞬态属性。
容许以 null 类型平安的形式进行更强壮的类型过滤(例如,不限于仅应用正则表达式表白类型)。
咱们当初 MappingPdxSerializer 更具体地探讨 的每个性能。

9.4.1. 自定义 PdxSerializer 注册
这 MappingPdxSerializer 使您可能 PdxSerializers 依据实体的字段或属性名称和类型注册自定义。

例如,假如您曾经定义了一个建模 a 的实体类型 User,如下所示:

package example.app.security.auth.model;

public class User {

private String name;

private Password password;


}
尽管用户名可能不须要任何非凡逻辑来序列化值,但另一方面,序列化明码可能须要额定的逻辑来解决字段或属性的敏感性质。

兴许您想在通过网络在客户端和服务器之间发送值时爱护明码,而不仅仅是 TLS,并且您只想存储加盐哈希。应用时 MappingPdxSerializer,能够注册一个自定义 PdxSerializer 来解决用户的明码,如下:

示例 5.PdxSerializers 按 POJO 字段 / 属性类型注册自定义

Map<?, PdxSerializer> customPdxSerializers = new HashMap<>();

customPdxSerializers.put(Password.class, new SaltedHashPasswordPdxSerializer());

mappingPdxSerializer.setCustomPdxSerializers(customPdxSerializers);

SaltedHashPasswordPdxSerializer 应用 Password 应用程序域模型类型注册利用程序定义的实例后,MappingPdxSerializer 将征询自定义 PdxSerializer 以序列化和反序列化所有 Password 对象,而不论蕴含对象(例如,User)。

然而,假如您想自定义的序列化 Passwords 只 User 对象。为此,您能够通过指定字段或属性的齐全限定名称 PdxSerializer 来为该 User 类型注册自定义 Class’s,如以下示例所示:

示例 6.PdxSerializers 通过 POJO 字段 / 属性名称注册自定义

Map<?, PdxSerializer> customPdxSerializers = new HashMap<>();

customPdxSerializers.put(“example.app.security.auth.model.User.password”, new SaltedHashPasswordPdxSerializer());

mappingPdxSerializer.setCustomPdxSerializers(customPdxSerializers);
请留神应用齐全限定的字段或属性名称(即
example.app.security.auth.model.User.password)作为自定义 PdxSerializer 注册键。

你能够通过应用一个更合乎逻辑的代码片段,如上面的构造注册码:User.class.getName().concat(“.password”);。咱们在后面显示的示例中举荐了这一点。后面的示例试图尽可能明确地阐明注册的语义。

9.4.2. 映射 ID 属性
与 Apache Geode 一样
ReflectionBasedAutoSerializer,SDGMappingPdxSerializer 也可能确定实体的标识符。然而,MappingPdxSerializer 这是通过应用 Spring Data 的映射元数据来实现的,特地是通过应用 Spring Data 的 @Id 正文查找指定为标识符的实体属性。或者,任何名为“id”的字段或属性,未明确用 正文 @Id,也被指定为实体的标识符。

例如:

class Customer {

@Id
Long id;


}
在这种状况下,该 Customer id 字段被标记为 PDX 类型元数据中的标识符字段,在序列化过程中调用
PdxWriter.markIdentifierField(:String) 该 PdxSerializer.toData(..) 办法时应用。

9.4.3. 映射只读属性
当您的实体定义只读属性时会产生什么?

首先,理解什么是“只读”属性很重要。如果您依照 JavaBeans 标准定义 POJO(如 Spring 所做的那样),您能够定义一个具备只读属性的 POJO,如下所示:

package example;

class ApplicationDomainType {

private AnotherType readOnly;

public AnotherType getReadOnly() [

this.readOnly;

}


}
该 readOnly 属性是只读的,因为它不提供 setter 办法。它只有一个 getter 办法。在这种状况下,readOnly 属性(不要与 readOnly DomainType 字段混同)被认为是只读的。

其后果是,在 MappingPdxSerializer 将不会尝试填充的实例时设置此属性的一个值 ApplicationDomainType 的 PdxSerializer.fromData(:Class<ApplicationDomainType>, :PdxReader)反序列化过程的办法,尤其是当的值是存在于 PDX 序列字节。

这在您可能要返回某个实体类型的视图或投影并且只想设置可写状态的状况下很有用。兴许实体的视图或投影基于受权或其余一些规范。要害是,您能够依据应用程序的用例和要求来利用此性能。如果您心愿始终写入字段或属性,只需定义一个 setter 办法。

9.4.4. 映射瞬态属性
同样,当您的实体定义 transient 属性时会产生什么?

transient 在序列化实体时,您心愿实体的字段或属性不会被序列化为 PDX。这正是产生的事件,不像 Apache Geode 本人的
ReflectionBasedAutoSerializer,它通过 Java 反射序列化对象可拜访的所有内容。

该 MappingPdxSerializer 不会序列化是合格的为暂时性的任何字段或属性,无论是应用 Java 自身的 transient 关键字(在类的实例字段的状况下)或者通过应用 @Transient 对字段或属性秋季数据注解。

例如,您能够定义一个具备瞬态字段和属性的实体,如下所示:

package example;

class Process {

private transient int id;

private File workingDirectory;

private String name;

private Type type;

@Transient
public String getHostname() {

...

}


}
无论是 Process id 现场还是可读的 hostname 财产被写入 PDX。

9.4.5. 按类类型过滤
与 Apache Geode 相似
ReflectionBasedAutoSerializer,SDGMappingPdxSerializer 容许您过滤序列化和反序列化的对象类型。

然而,与 Apache
GeodeReflectionBasedAutoSerializer 应用简单的正则表达式来表白序列化程序处理的类型不同,SDGMappingPdxSerializer 应用更弱小的 java.util.function.Predicate 接口和 API 来表白类型匹配规范。

如果你喜爱应用正则表达式,你能够实现一个 Predicateusing Java 的 正则表达式反对。

对于 Java 的丑陋的局部 Predicate 界面,你能够撰写 Predicates 通过应用便捷和适当的 API 办法,包含:and(:Predicate),or(:Predicate),和 negate()。

以下示例显示了 PredicateAPI 的运行状况:

Predicate<Class<?>> customerTypes =
type -> Customer.class.getPackage().getName().startsWith(type.getName()); // Include all types in the same package as Customer

Predicate includedTypes = customerTypes
.or(type -> User.class.isAssignble(type)); // Additionally, include User sub-types (e.g. Admin, Guest, etc)

mappingPdxSerializer.setIncludeTypeFilters(includedTypes);

mappingPdxSerializer.setExcludeTypeFilters(
type -> !Reference.class.getPackage(type.getPackage()); // Exclude Reference types
Class 传递给您的 任何对象 Predicate 都保障不是 null.

SDGMappingPdxSerializer 包含对蕴含和排除类类型过滤器的反对。

排除类型过滤
默认状况下,SDG 的 MappingPdxSerializer 寄存器预约义 Predicates 该过滤器,或从以下包中排除类型:

java.*
com.gemstone.gemfire.*
org.apache.geode.*
org.springframework.*
此外,调用 和调用时的 MappingPdxSerializer 过滤器 null 对象 PdxSerializer.toData(:Object, :PdxWriter)null 调用 PdxSerializer.fromData(:Class<?>, :PdxReader)办法时的类类型。

很容易为其余类类型或整个类型包增加排除项,只需定义 aPredicate 并将其增加到 MappingPdxSerializer 后面所示的。


MappingPdxSerializer.setExcludeTypeFilters(:Predicate<Class<?>>) 办法是可加的,这意味着它将您的利用程序定义的类型过滤器与 Predicates 下面应用该 Predicate.and(:Predicate<Class<?>>)办法批示的现有的、预约义的类型过滤器组合在一起。

然而,如果您想蕴含 java.security Principal 被排除类型过滤器隐式排除的类类型(例如,)怎么办?请参阅蕴含类型过滤。

蕴含类型过滤
如果要显式蕴含类类型,或笼罩隐式排除应用程序所需的类类型的类类型过滤器(例如,java.security.Principal 默认状况下应用 java.* 包排除类型过滤器将排除在 上 MappingPdxSerializer),则只需定义适当的 Predicate 并将其增加到应用
MappingPdxSerializer.setIncludeTypeFilters(:Predicate<Class<?>>) 办法的序列化程序中,如下所示:

Predicate<Class<?>> principalTypeFilter =
type -> java.security.Principal.class.isAssignableFrom(type);

mappingPdxSerializer.setIncludeTypeFilters(principalTypeFilters);
同样,该
MappingPdxSerializer.setIncludeTypeFilters(:Predicate<Class<?>>) 办法,如 setExcludeTypeFilters(:Predicate<Class<?>>),是可加的,因而应用 组成任何传递类型过滤器 Predicate.or(:Predicate<Class<?>>)。这意味着你能够打电话 setIncludeTypeFilters(:Predicate<Class<?>>) 依据须要屡次。

当蕴含类型过滤器存在时,MappingPdxSerializer 当类类型未被隐式排除或当类类型被显式蕴含时,以返回 true 的形式决定是否反 / 序列化类类型的实例。而后,类类型的实例将被适当地序列化或反序列化。

例如,当一个类型过滤器 Predicate<Class<Principal>> 如后面所示被显式注册时,它会勾销对 java.* 包类型的隐式排除类型过滤器。

退出移动版