原题目:Spring认证中国教育管理中心-Apache Geode 的 Spring 数据教程二十五(Spring中国教育管理中心)
Apache Geode 的 Spring 数据教程二十五
- Apache Lucene 集成
Apache Geode与Apache Lucene集成,让您能够应用 Lucene 查问索引和搜寻存储在 Apache Geode 中的数据。基于搜寻的查问还包含翻阅查问后果的能力。
此外,Spring Data for Apache Geode 增加了对基于 Spring Data Commons 投影基础设施的查问投影的反对。此性能使查问后果能够依据应用程序的须要投影到一流的应用程序域类型中。
Lucene的Index任何Lucene的基于搜寻的查问能够运行之前必须创立。ALuceneIndex 能够在 Spring (Data for Apache Geode) XML 配置中创立,如下所示:
<gfe:lucene-index id="IndexOne" fields="fieldOne, fieldTwo" region-path="/Example"/>
此外,Apache Lucene 容许为 每个字段指定分析器,并且能够依照以下示例进行配置:
<gfe:lucene-index id="IndexTwo" lucene-service-ref="luceneService" region-path="/AnotherExample">
<gfe:field-analyzers> <map> <entry key="fieldOne"> <bean class="example.AnalyzerOne"/> </entry> <entry key="fieldTwo"> <bean class="example.AnalyzerTwo"/> </entry> </map></gfe:field-analyzers>
</gfe:lucene-index>
的Map能够被指定为一个顶级bean定义,并通过应用所援用的ref在嵌套属性<gfe:field-analyzers>元素,如下: <gfe-field-analyzers ref="
refToTopLevelMapBeanDefinition"/>。
Spring Data for Apache Geode 的LuceneIndexFactoryBeanAPI 和 SDG 的 XML 命名空间也容许
org.apache.geode.cache.lucene.LuceneSerializer 在创立LuceneIndex. 将LuceneSerializer容许您配置对象将转换为Lucene的文件进行索引当对象被索引的形式。
上面的示例演示如何将增加LuceneSerializer到LuceneIndex:
<bean id="MyLuceneSerializer" class="example.CustomLuceneSerializer"/>
<gfe:lucene-index id="IndexThree" lucene-service-ref="luceneService" region-path="/YetAnotherExample">
<gfe:lucene-serializer ref="MyLuceneSerializer">
</gfe:lucene-index>
您也能够将 指定LuceneSerializer为匿名的嵌套 bean 定义,如下所示:
<gfe:lucene-index id="IndexThree" lucene-service-ref="luceneService" region-path="/YetAnotherExample">
<gfe:lucene-serializer> <bean class="example.CustomLuceneSerializer"/></gfe:lucene-serializer>
</gfe:lucene-index>
或者,您能够LuceneIndex在 Spring Java 配置中的@Configuration类中申明或定义一个,如以下示例所示:
@Bean(name = "Books")
@DependsOn("bookTitleIndex")
PartitionedRegionFactoryBean<Long, Book> booksRegion(GemFireCache gemfireCache) {
PartitionedRegionFactoryBean<Long, Book> peopleRegion = new PartitionedRegionFactoryBean<>();peopleRegion.setCache(gemfireCache);peopleRegion.setClose(false);peopleRegion.setPersistent(false);return peopleRegion;
}
@Bean
LuceneIndexFactoryBean bookTitleIndex(GemFireCache gemFireCache,
LuceneSerializer luceneSerializer) {LuceneIndexFactoryBean luceneIndex = new LuceneIndexFactoryBean();luceneIndex.setCache(gemFireCache);luceneIndex.setFields("title");luceneIndex.setLuceneSerializer(luceneSerializer);luceneIndex.setRegionPath("/Books");return luceneIndex;
}
@Bean
CustomLuceneSerializer myLuceneSerialier() {
return new CustomeLuceneSerializer();
}
Apache Geode 的 Spring 数据教程二十五
Apache Geode 的 Apache Lucene 集成和反对存在一些限度。
首先,LuceneIndex只能在 Apache Geode PARTITIONRegion上创立。
其次,所有LuceneIndexes必须在利用的区域之前创立LuceneIndex。
为了帮忙确保LuceneIndexes在 Spring 容器中定义的所有申明都是在它们利用的区域之前创立的,SDG 包含
org.springframework.data.gemfire.config.support.LuceneIndexRegionBeanFactoryPostProcessor. 您能够BeanFactoryPostProcessor 应用.xml在 XML 配置中注册这个 Spring <bean class="org.springframework.data.gemfire.config.support.LuceneIndexRegionBeanFactoryPostProcessor"/>。在o.s.d.g.config.support.LuceneIndexRegionBeanFactoryPostProcessor应用SDG XML配置时,仅可应用。BeanFactoryPostProcessors能够在此处找到无关 Spring 的更多详细信息。
这些 Apache Geode 限度可能不适用于将来版本,这就是为什么 SDG LuceneIndexFactoryBeanAPI 也间接援用区域,而不仅仅是区域门路。
当您想LuceneIndex在应用程序生命周期的稍后工夫点依据需要在现有区域上定义带有数据的区域时,这是更现实的抉择。在可能的状况下,SDG 致力保持强类型对象。然而,目前您必须应用该regionPath属性来指定利用的区域LuceneIndex。
此外,在后面的示例中,请留神 Spring@DependsOn对BooksRegion bean 定义的正文的存在。这会创立从BooksRegion bean 到bookTitleIndex LuceneIndexbean 定义的依赖关系,确保LuceneIndex在它利用的 Region 之前创立它。
既然有了LuceneIndex,咱们就能够执行基于 Lucene 的数据拜访操作,例如查问。
12.1.Lucene 模板数据拜访器
Spring Data for Apache Geode 为 Lucene 数据拜访操作提供了两个次要模板,具体取决于您的应用程序筹备解决的级别有多低。
该LuceneOperations接口应用 Apache Geode Lucene types定义查问操作 ,其定义在以下接口定义中:
public interface LuceneOperations {
<K, V> List<LuceneResultStruct<K, V>> query(String query, String defaultField [, int resultLimit] , String... projectionFields);<K, V> PageableLuceneQueryResults<K, V> query(String query, String defaultField, int resultLimit, int pageSize, String... projectionFields);<K, V> List<LuceneResultStruct<K, V>> query(LuceneQueryProvider queryProvider [, int resultLimit] , String... projectionFields);<K, V> PageableLuceneQueryResults<K, V> query(LuceneQueryProvider queryProvider, int resultLimit, int pageSize, String... projectionFields);<K> Collection<K> queryForKeys(String query, String defaultField [, int resultLimit]);<K> Collection<K> queryForKeys(LuceneQueryProvider queryProvider [, int resultLimit]);<V> Collection<V> queryForValues(String query, String defaultField [, int resultLimit]);<V> Collection<V> queryForValues(LuceneQueryProvider queryProvider [, int resultLimit]);
}
Apache Geode 的 Spring 数据教程二十五
在操作LuceneOperations界面匹配由Apache的Geode的提供的操作 LuceneQuery接口。然而,SDG 具备将专有 Apache Geode 或 Apache LuceneExceptions 转换为 Spring 高度一致且富裕表现力的 DAO 异样层次结构的附加价值,特地是当许多古代数据拜访操作波及多个存储或存储库时。
此外,SDG 的LuceneOperations接口能够爱护您的应用程序免受底层 Apache Geode 或 Apache Lucene API 引入的接口破坏性更改的影响。
然而,提供仅应用 Apache Geode 和 Apache Lucene 数据类型(例如 Apache Geode 的LuceneResultStruct)的 Lucene 数据拜访对象 (DAO) 将是可悲的。因而,SDG 为您提供了
ProjectingLuceneOperations解决这些重要利用问题的 接口。以下清单显示了ProjectingLuceneOperations接口定义:
public interface ProjectingLuceneOperations {
<T> List<T> query(String query, String defaultField [, int resultLimit], Class<T> projectionType);<T> Page<T> query(String query, String defaultField, int resultLimit, int pageSize, Class<T> projectionType);<T> List<T> query(LuceneQueryProvider queryProvider [, int resultLimit], Class<T> projectionType);<T> Page<T> query(LuceneQueryProvider queryProvider, int resultLimit, int pageSize, Class<T> projectionType);
}
该
ProjectingLuceneOperations接口次要应用应用程序域对象类型,让您能够应用应用程序数据。该query办法的变体承受一个投影类型和模板能够应用Spring的数据共享基础设施的投影利用的查问后果给定的投影类型的实例。
此外,该模板将分页的 Lucene 查问后果包装在 Spring Data CommonsPage形象的实例中 。雷同的投影逻辑依然能够利用于页面中的后果,并在拜访汇合中的每个页面时提早投影。
举例来说,假如您有一个示意 a 的类Person,如下所示:
class Person {
Gender gender;LocalDate birthDate;String firstName;String lastName;...String getName() { return String.format("%1$s %2$s", getFirstName(), getLastName());}
}
此外,Customers依据您的应用程序视图,您可能有一个独自的界面来将人员示意为,如下所示:
interface Customer {
String getName()
}
如果我定义以下内容LuceneIndex......
@Bean
LuceneIndexFactoryBean personLastNameIndex(GemFireCache gemfireCache) {
LuceneIndexFactoryBean personLastNameIndex = new LuceneIndexFactoryBean();personLastNameIndex.setCache(gemfireCache);personLastNameIndex.setFields("lastName");personLastNameIndex.setRegionPath("/People");return personLastNameIndex;
}
而后您能够将人作为Person对象进行查问,如下所示:
List<Person> people = luceneTemplate.query("lastName: D*", "lastName", Person.class);
或者,您能够查问 a Pageof type Customer,如下所示:
Page<Customer> customers = luceneTemplate.query("lastName: D*", "lastName", 100, 20, Customer.class);
该Page则能够用来获取后果的单个页面,如下所示:
List<Customer> firstPage = customers.getContent();
不便的是,Spring Data CommonsPage接口还实现了java.lang.Iterable<T>,从而能够轻松地对内容进行迭代。
Spring Data Commons Projection 根底构造的惟一限度是投影类型必须是接口。然而,能够扩大提供的 SDC Projection 根底构造并提供ProjectionFactory 应用CGLIB生成代理类作为投影实体的自定义 。
您能够应用在 Lucene 模板上setProjectionFactory(:ProjectionFactory)设置自定义ProjectionFactory。
12.2.正文配置反对
最初,Spring Data for Apache Geode 为LuceneIndexes.
最终,SDG Lucene 反对将进入 Apache Geode 的 Repository 基础设施扩大,以便 Lucene 查问能够示意为应用程序Repository接口上的办法,与OQL 反对明天的工作形式大致相同。
然而,与此同时,如果您想不便地表白LuceneIndexes,您能够间接在您的应用程序域对象上进行,如下例所示:
@PartitionRegion("People")
class Person {
Gender gender;@IndexLocalDate birthDate;String firstName;@LuceneIndex;String lastName;...
}
要启用此性能,您必须应用 SDG 的注解配置反对,特地是 @EnableEntityDefineRegions和@EnableIndexing注解,如下所示:
@PeerCacheApplication
@EnableEntityDefinedRegions
@EnableIndexing
class ApplicationConfiguration {
...
}
LuceneIndexes只能在 Apache Geode 服务器上创立,因为LuceneIndexes仅实用于PARTITION区域。
鉴于咱们之前对Person类的定义,SDG 正文配置反对找到Person实体类定义并确定人员存储在PARTITION名为“人员”的区域中,并且Person具备 OQL IndexonbirthDate和LuceneIndexon lastName。
- 在 Apache Geode 中疏导 Spring ApplicationContext
通常,基于 Spring 的应用程序通过应用 Spring Data for Apache Geode 的性能来疏导 Apache Geode。通过指定<gfe:cache/>应用 Spring Data for Apache Geode XML 命名空间的元素,Cache在与应用程序雷同的 JVM 过程中应用默认设置创立和初始化单个嵌入式 Apache Geode 对等实例。
然而,有时须要(可能是您的 IT 组织强制要求)Apache Geode 由提供的 Apache Geode 工具套件齐全治理和操作,可能应用 Gfsh。通过应用Gfsh,Apache Geode 疏导您的 SpringApplicationContext而不是相同。Apache Geode 不是应用 Spring Boot 的应用程序服务器或 Java 主类,而是进行疏导并托管您的应用程序。
Apache Geode 不是应用程序服务器。此外,在波及 Apache Geode 缓存配置的状况下,应用这种办法存在限度。
13.1.应用 Apache Geode 从 Gfsh 开始疏导 Spring 上下文
为了启动一个春天ApplicationContext开始应用的Apache服务器的Geode时在Apache中的Geode Gfsh,则必须应用Apache的Geode的 initalizer能力。初始化程序块能够申明在缓存由 Apache Geode 初始化后启动的应用程序回调。
一个初始化申明的内初始化通过应用Apache的Geode的原生的最小片段元素cache.xml。要疏导 Spring ApplicationContext,cache.xml须要一个文件,这与疏导ApplicationContext应用组件扫描配置的 Spring 所需的最小 Spring XML 配置片段十分类似(例如<context:component-scan base-packages="…"/>)。
侥幸的是,框架曾经不便地提供了这样的初始化程序:
SpringContextBootstrappingInitializer.
以下示例显示了 Apache Geodecache.xml文件中此类的典型但最小的配置 :
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache https://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
<initializer>
<class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name><parameter name="contextConfigLocations"> <string>classpath:application-context.xml</string></parameter>
</initializer>
</cache>
本
SpringContextBootstrappingInitializer类遵循相似于Spring的约定ContextLoaderListener 类,它是用来启动一个春天ApplicationContext的Web应用程序,其中外面ApplicationContext 的配置文件与指定的contextConfigLocationsservlet上下文参数。
此外,
SpringContextBootstrappingInitializer该类还能够与basePackages参数一起应用,以指定蕴含适当正文的应用程序组件的根本包的逗号分隔列表。Spring 容器搜寻这些组件以在类门路中查找并创立 Spring bean 和其余应用程序组件,如下例所示:
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache https://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
<initializer>
<class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name><parameter name="basePackages"> <string>org.mycompany.myapp.services,org.mycompany.myapp.dao,...</string></parameter>
</initializer>
</cache>
而后,用适当的配置和结构CLASSPATH及cache.xml文件(后面示出)开始在阿帕奇的Geode服务器时指定为命令行选项Gfsh,命令行会是如下所示:
gfsh>start server --name=ExampleServer --log-level=config ...
--classpath="/path/to/application/classes.jar:/path/to/spring-data-geode-<major>.<minor>.<maint>.RELEASE.jar"--cache-xml-file="/path/to/geode/cache.xml"
该application-context.xml能够是任何无效的Spring配置元数据,包含所有的SDG XML命名空间的元素。这种办法的惟一限度是无奈应用 SDG XML 命名空间配置 Apache Geode 缓存。换言之,没有任何的<gfe:cache/>元素属性(如cache-xml-location,properties-ref,critical-heap-percentage,pdx-serializer-ref,lock-lease,和其它物质)能够被指定。如果应用,这些属性将被疏忽。
这样做的起因是 Apache Geode 自身曾经在调用初始化程序之前创立并初始化了缓存。因而,缓存曾经存在,并且因为它是“单例”,因而无奈从新初始化或减少其任何配置。
13.2.懈怠布线 Apache Geode 组件
Spring Data for Apache Geode 曾经提供了对主动拆卸 Apache Geode 组件(例如CacheListeners、 CacheLoaders、CacheWriters等等)的反对,这些组件由 Apache Geodecache.xml应用 SDG 的WiringDeclarableSupport类申明和创立,如应用主动拆卸和正文的配置中所述。然而,这仅在 Spring 执行疏导程序时(即,当 Spring 疏导 Apache Geode 时)才无效。
当您的 SpringApplicationContext由 Apache Geode 疏导时,这些 Apache Geode 应用程序组件ApplicationContext不会被留神到,因为 Spring尚不存在。ApplicationContext在 Apache Geode 调用初始化程序块之前不会创立Spring ,这仅在所有其余 Apache Geode 组件(缓存、区域等)都曾经创立和初始化之后产生。
为了解决这个问题,
LazyWiringDeclarableSupport引入了一个新类。这个新类晓得 Spring ApplicationContext。这个形象基类背地的用意是任何实现类都将本人注册为由 Spring 容器配置,一旦调用初始化程序,该容器最终由 Apache Geode 创立。从实质上讲,这使您的 Apache Geode 应用程序组件有机会应用 Spring 容器中定义的 Spring bean 进行配置和主动连贯。
为了让您的 Apache Geode 应用程序组件由 Spring 容器主动连贯,您应该创立一个应用程序类,该类扩大
LazyWiringDeclarableSupport并正文须要作为 Spring bean 依赖项提供的任何类成员,相似于以下示例:
public class UserDataSourceCacheLoader extends LazyWiringDeclarableSupport
implements CacheLoader<String, User> {
@Autowired
private DataSource userDataSource;
...
}
正如CacheLoader下面的示例所暗示的那样,您可能必须(只管很少)CacheListener在 Apache Geode 中同时定义了 Region 和组件cache.xml。在CacheLoader可能须要拜访应用程序存储库(或者一个JDBCDataSource在Spring中定义ApplicationContext)加载Users到阿帕奇的GeodeREPLICATE区上启动。
正告
以这种形式将 Apache Geode 和 Spring 容器的不同生命周期混合在一起时要小心。并非所有用例和场景都受反对。Apache Geodecache.xml配置相似于以下内容(来自 SDG 的测试套件):
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache https://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
<region name="Users" refid="REPLICATE">
<region-attributes initial-capacity="101" load-factor="0.85"> <key-constraint>java.lang.String</key-constraint> <value-constraint>org.springframework.data.gemfire.repository.sample.User</value-constraint> <cache-loader> <class-name> org.springframework.data.gemfire.support.SpringContextBootstrappingInitializerIntegrationTests$UserDataStoreCacheLoader </class-name> </cache-loader></region-attributes>
</region>
<initializer>
<class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name><parameter name="basePackages"> <string>org.springframework.data.gemfire.support.sample</string></parameter>
</initializer>
</cache>
Apache Geode 的 Spring 数据教程二十五