(1). 概述
在这一篇,主要剖析ElasticsearchRepository的具体实现.
(2). RepositoryFactoryBeanSupport
public void afterPropertiesSet() {
this.factory = createRepositoryFactory();
this.factory.setQueryLookupStrategyKey(queryLookupStrategyKey);
this.factory.setNamedQueries(namedQueries);
this.factory.setEvaluationContextProvider(evaluationContextProvider.orElseGet(() -> QueryMethodEvaluationContextProvider.DEFAULT));
this.factory.setBeanClassLoader(classLoader);
this.factory.setBeanFactory(beanFactory);
if (publisher != null) {
this.factory.addRepositoryProxyPostProcessor(new EventPublishingRepositoryProxyPostProcessor(publisher));
}
repositoryBaseClass.ifPresent(this.factory::setRepositoryBaseClass);
this.repositoryFactoryCustomizers.forEach(customizer -> customizer.customize(this.factory));
RepositoryFragments customImplementationFragment = customImplementation //
.map(RepositoryFragments::just) //
.orElseGet(RepositoryFragments::empty);
RepositoryFragments repositoryFragmentsToUse = this.repositoryFragments //
.orElseGet(RepositoryFragments::empty) //
.append(customImplementationFragment);
this.repositoryMetadata = this.factory.getRepositoryMetadata(repositoryInterface);
// Make sure the aggregate root type is present in the MappingContext (e.g. for auditing)
this.mappingContext.ifPresent(it -> it.getPersistentEntity(repositoryMetadata.getDomainType()));
// *************************************************************************************
// 1. 委托给ElasticsearchRepositoryFactory创建:Repository
// *************************************************************************************
this.repository = Lazy.of(() -> this.factory.getRepository(repositoryInterface, repositoryFragmentsToUse));
if (!lazyInit) {
this.repository.get();
} // end
}
(3). RepositoryFactorySupport
public <T> T getRepository(Class<T> repositoryInterface, RepositoryFragments fragments) {
if (logger.isDebugEnabled()) {
logger.debug(LogMessage.format("Initializing repository instance for %s…", repositoryInterface.getName()));
}
Assert.notNull(repositoryInterface, "Repository interface must not be null!");
Assert.notNull(fragments, "RepositoryFragments must not be null!");
RepositoryMetadata metadata = getRepositoryMetadata(repositoryInterface);
RepositoryComposition composition = getRepositoryComposition(metadata, fragments);
RepositoryInformation information = getRepositoryInformation(metadata, composition);
validate(information, composition);
// target = SimpleElasticsearchRepository
Object target = getTargetRepository(information);
// *************************************************************************************
// 2. 根据接口创建动态代理.
// *************************************************************************************
// Create proxy
ProxyFactory result = new ProxyFactory();
// target = SimpleElasticsearchRepository
result.setTarget(target);
result.setInterfaces(repositoryInterface, Repository.class, TransactionalProxy.class);
if (MethodInvocationValidator.supports(repositoryInterface)) {
result.addAdvice(new MethodInvocationValidator());
}
result.addAdvisor(ExposeInvocationInterceptor.ADVISOR);
postProcessors.forEach(processor -> processor.postProcess(result, information));
if (DefaultMethodInvokingMethodInterceptor.hasDefaultMethods(repositoryInterface)) {
result.addAdvice(new DefaultMethodInvokingMethodInterceptor());
}
ProjectionFactory projectionFactory = getProjectionFactory(classLoader, beanFactory);
Optional<QueryLookupStrategy> queryLookupStrategy = getQueryLookupStrategy(queryLookupStrategyKey,
evaluationContextProvider);
result.addAdvice(new QueryExecutorMethodInterceptor(information, projectionFactory, queryLookupStrategy,
namedQueries, queryPostProcessors, methodInvocationListeners));
composition = composition.append(RepositoryFragment.implemented(target));
result.addAdvice(new ImplementationMethodExecutionInterceptor(information, composition, methodInvocationListeners));
// *************************************************************************************
// 3. 创建动态代理之后的对象
// *************************************************************************************
T repository = (T) result.getProxy(classLoader);
if (logger.isDebugEnabled()) {
logger
.debug(LogMessage.format("Finished creation of repository instance for {}.", repositoryInterface.getName()));
}
// 返回动态代理的对象
return repository;
}
(4). 总结
从上面的分析结果能看出,ElasticsearchRepository接口的所有操作,全都会委派给SimpleElasticsearchRepository.