一、Repository Bean 是如何创建的
1、JpaRepositoriesRegistrar
2、RepositoryBeanDefifinitionRegistrarSupport.registerBeanDefifinitions (JpaRepositoriesRegistrar的父类)
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.data.jpa.repository.config;
import java.lang.annotation.Annotation;
import org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
class JpaRepositoriesRegistrar extends RepositoryBeanDefinitionRegistrarSupport {
JpaRepositoriesRegistrar() {
}
protected Class<? extends Annotation> getAnnotation() {
return EnableJpaRepositories.class;//告诉它是@EnableJpaRepositories这个注解
}
protected RepositoryConfigurationExtension getExtension() {//扩展
return new JpaRepositoryConfigExtension();
}
}
以下是RepositoryBeanDefinitionRegistararSupport(用于为 repository 接口动态地
创建 bean 定义。)
//省略了一些代码,只显示关键代码
package org.springframework.data.repository.config;
public abstract class RepositoryBeanDefinitionRegistrarSupport implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {//主要是一些配置信息
Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null!");
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
Assert.notNull(this.resourceLoader, "ResourceLoader must not be null!");
if (annotationMetadata.getAnnotationAttributes(this.getAnnotation().getName()) != null) {
AnnotationRepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(annotationMetadata, this.getAnnotation(), this.resourceLoader, this.environment, registry);
RepositoryConfigurationExtension extension = this.getExtension();
RepositoryConfigurationUtils.exposeRegistration(extension, registry, configurationSource);
RepositoryConfigurationDelegate delegate = new RepositoryConfigurationDelegate(configurationSource, this.resourceLoader, this.environment);
delegate.registerRepositoriesIn(registry, extension);//调用此方法进行注册Repository
}
}
}
以下是registerRepositoriesIn方法(用于注册 repository bean 定义。)
public List<BeanComponentDefinition> registerRepositoriesIn(BeanDefinitionRegistry registry, RepositoryConfigurationExtension extension) {
if (LOG.isInfoEnabled()) {
LOG.info("Bootstrapping Spring Data repositories in {} mode.", this.configurationSource.getBootstrapMode().name());
}
extension.registerBeansForRoot(registry, this.configurationSource);
//定义一个builder
RepositoryBeanDefinitionBuilder builder = new RepositoryBeanDefinitionBuilder(registry, extension, this.configurationSource, this.resourceLoader, this.environment);
//将Repository接口一个一个拉出来
List<BeanComponentDefinition> definitions = new ArrayList();
StopWatch watch = new StopWatch();
if (LOG.isDebugEnabled()) {
LOG.debug("Scanning for repositories in packages {}.", this.configurationSource.getBasePackages().stream().collect(Collectors.joining(", ")));
}
watch.start();
Collection<RepositoryConfiguration<RepositoryConfigurationSource>> configurations = extension.getRepositoryConfigurations(this.configurationSource, this.resourceLoader, this.inMultiStoreMode);
Map<String, RepositoryConfiguration<?>> configurationsByRepositoryName = new HashMap(configurations.size());
Iterator var8 = configurations.iterator();
//然后一个一个地为他们进行beanDefinitions的定义
while(var8.hasNext()) {
RepositoryConfiguration<? extends RepositoryConfigurationSource> configuration = (RepositoryConfiguration)var8.next();
configurationsByRepositoryName.put(configuration.getRepositoryInterface(), configuration);
//用build进行了创建
BeanDefinitionBuilder definitionBuilder = builder.build(configuration);
extension.postProcess(definitionBuilder, this.configurationSource);
if (this.isXml) {
extension.postProcess(definitionBuilder, (XmlRepositoryConfigurationSource)this.configurationSource);
} else {
extension.postProcess(definitionBuilder, (AnnotationRepositoryConfigurationSource)this.configurationSource);
}
AbstractBeanDefinition beanDefinition = definitionBuilder.getBeanDefinition();
String beanName = this.configurationSource.generateBeanName(beanDefinition);
if (LOG.isTraceEnabled()) {
LOG.trace("Spring Data {} - Registering repository: {} - Interface: {} - Factory: {}", new Object[]{extension.getModuleName(), beanName, configuration.getRepositoryInterface(), configuration.getRepositoryFactoryBeanClassName()});
}
beanDefinition.setAttribute("factoryBeanObjectType", configuration.getRepositoryInterface());
//把bean的属性放进去
registry.registerBeanDefinition(beanName, beanDefinition);
definitions.add(new BeanComponentDefinition(beanDefinition, beanName));
}
potentiallyLazifyRepositories(configurationsByRepositoryName, registry, this.configurationSource.getBootstrapMode());
watch.stop();
if (LOG.isInfoEnabled()) {
LOG.info("Finished Spring Data repository scanning in {}ms. Found {} repository interfaces.", watch.getLastTaskTimeMillis(), configurations.size());
}
return definitions;
}
以下是build方法(构建 repository bean 定义。)
public BeanDefinitionBuilder build(RepositoryConfiguration<?> configuration) {
Assert.notNull(this.registry, "BeanDefinitionRegistry must not be null!");
Assert.notNull(this.resourceLoader, "ResourceLoader must not be null!");
//取得类名
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(configuration.getRepositoryFactoryBeanClassName());
//设置属性
builder.getRawBeanDefinition().setSource(configuration.getSource());
builder.addConstructorArgValue(configuration.getRepositoryInterface());
builder.addPropertyValue("queryLookupStrategyKey", configuration.getQueryLookupStrategyKey());
builder.addPropertyValue("lazyInit", configuration.isLazyInit());
builder.setLazyInit(configuration.isLazyInit());
configuration.getRepositoryBaseClassName().ifPresent((it) -> {
builder.addPropertyValue("repositoryBaseClass", it);
});
NamedQueriesBeanDefinitionBuilder definitionBuilder = new NamedQueriesBeanDefinitionBuilder(this.extension.getDefaultNamedQueryLocation());
configuration.getNamedQueriesLocation().ifPresent(definitionBuilder::setLocations);
builder.addPropertyValue("namedQueries", definitionBuilder.build(configuration.getSource()));
this.registerCustomImplementation(configuration).ifPresent((it) -> {
builder.addPropertyReference("customImplementation", it);
builder.addDependsOn(it);
});
BeanDefinitionBuilder fragmentsBuilder = BeanDefinitionBuilder.rootBeanDefinition(RepositoryFragmentsFactoryBean.class);
List<String> fragmentBeanNames = (List)this.registerRepositoryFragmentsImplementation(configuration).map(RepositoryFragmentConfiguration::getFragmentBeanName).collect(Collectors.toList());
fragmentsBuilder.addConstructorArgValue(fragmentBeanNames);
builder.addPropertyValue("repositoryFragments", ParsingUtils.getSourceBeanDefinition(fragmentsBuilder, configuration.getSource()));
return builder;
}
以下是JpaRepositoryConfigExtension(用于为 JPA repository 提供配置支持。)
//以下非完整代码
package org.springframework.data.jpa.repository.config;
//扩展
public class JpaRepositoryConfigExtension extends RepositoryConfigurationExtensionSupport {
private static final Class<?> PAB_POST_PROCESSOR = PersistenceAnnotationBeanPostProcessor.class;
private static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";
private static final String ENABLE_DEFAULT_TRANSACTIONS_ATTRIBUTE = "enableDefaultTransactions";
private static final String JPA_METAMODEL_CACHE_CLEANUP_CLASSNAME = "org.springframework.data.jpa.util.JpaMetamodelCacheCleanup";
public JpaRepositoryConfigExtension() {
}
public String getModuleName() {
return "JPA";
}
public String getRepositoryFactoryBeanClassName() {
return JpaRepositoryFactoryBean.class.getName();//获得我要注册的bean的类型
}
以下是JpaRepositoryFactoryBean(是 Spring Data JPA 提供的一个工厂 bean,用于创建 JPA repository 的实例。)
//非全部代码
public class JpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID> extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> {
//创建一个JpaRepositoryFactory,再在里面创建一个Repository
//所有操作执行完后调用afterPropertiesSet方法
public void afterPropertiesSet() {
Assert.state(this.entityManager != null, "EntityManager must not be null!");
super.afterPropertiesSet();
}
}
以下是afterPropertiesSet方法(用于在所有 bean 属性被设置后,执行一些必要的初始化工作。)
public void afterPropertiesSet() {
//仅展示主要代码
this.repository = Lazy.of(() -> {
return (Repository)this.factory.getRepository(this.repositoryInterface, repositoryFragmentsToUse);//创建对应的Repository的代理对象
});
if (!this.lazyInit) {
this.repository.get();
}
}
二、接⼝中的⽅法是如何被解释的(自己在接口中定义的方法是怎么回事)
RepositoryFactorySupport
用于创建 repository 实例。它的 getRepository
方法用于获取指定 repository 接口的实例。)
//getRepository 方法用于获取指定 repository 接口的实例
public <T> T getRepository(Class<T> repositoryInterface, RepositoryComposition.RepositoryFragments fragments) {
if (LOG.isDebugEnabled()) {
LOG.debug("Initializing repository instance for {}…", repositoryInterface.getName());
}
Assert.notNull(repositoryInterface, "Repository interface must not be null!");
Assert.notNull(fragments, "RepositoryFragments must not be null!");
RepositoryMetadata metadata = this.getRepositoryMetadata(repositoryInterface);
RepositoryComposition composition = this.getRepositoryComposition(metadata, fragments);
RepositoryInformation information = this.getRepositoryInformation(metadata, composition);
this.validate(information, composition);
Object target = this.getTargetRepository(information);
ProxyFactory result = new ProxyFactory();
result.setTarget(target);
result.setInterfaces(new Class[]{repositoryInterface, Repository.class, TransactionalProxy.class});
if (MethodInvocationValidator.supports(repositoryInterface)) {
result.addAdvice(new MethodInvocationValidator());
}
//添加了Advice,在创建 repository 实例时添加额外的逻辑
result.addAdvice(SurroundingTransactionDetectorMethodInterceptor.INSTANCE);
result.addAdvisor(ExposeInvocationInterceptor.ADVISOR);
this.postProcessors.forEach((processor) -> {
processor.postProcess(result, information);
});
result.addAdvice(new DefaultMethodInvokingMethodInterceptor());
ProjectionFactory projectionFactory = this.getProjectionFactory(this.classLoader, this.beanFactory);
//创建了QueryExecutorMethodInterceptor的一个拦截
result.addAdvice(new QueryExecutorMethodInterceptor(information, projectionFactory));
composition = composition.append(RepositoryFragment.implemented(target));
result.addAdvice(new ImplementationMethodExecutionInterceptor(composition));
T repository = result.getProxy(this.classLoader);
if (LOG.isDebugEnabled()) {
LOG.debug("Finished creation of repository instance for {}.", repositoryInterface.getName());
}
return repository;
}
以下是QueryExecutorMethodInterceptor里面的invoke(拦截器会根据方法的注解或参数类型等信息,确定当前方法需要执行的操作类型,例如查询、更新或删除等。)
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();//取得方法
return QueryExecutionConverters.getExecutionAdapter(method.getReturnType()).apply(() -> {
return this.resultHandler.postProcessInvocationResult(this.doInvoke(invocation), method);
});//到doInvoke
}
以下是QueryExecutorMethodInterceptor里面的doinvoke
@Nullable
private Object doInvoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
Object[] arguments = invocation.getArguments();
return this.hasQueryFor(method) ? ((RepositoryQuery)this.queries/*查询*/.get(method)).execute/*执行*/(arguments) : invocation.proceed();
}
语法解析(Part文件)