Spring Data JPA系列
2、Spring Data JPA Criteria查询、部分字段查询
3、Spring Data JPA数据批量插入、批量更新真的用对了吗
4、Spring Data JPA的一对一、LazyInitializationException异常、一对多、多对多操作
5、Spring Data JPA自定义Id生成策略、复合主键配置、Auditing使用
6、【源码】Spring Data JPA原理解析之Repository的自动注入(一)
7、【源码】Spring Data JPA原理解析之Repository的自动注入(二)
8、【源码】Spring Data JPA原理解析之Repository执行过程及SimpleJpaRepository源码
9、【源码】Spring Data JPA原理解析之Repository自定义方法命名规则执行原理(一)
前言
上一篇限于篇幅,只讲解了Repository对应的BeanDefinition加入到Spring容器。在Spring框架中,Bean的自动装载分为两步,第一步是扫描并注册Bean的BeanDefinition到Spring容器,第二步实例化Bean对象、属性赋值并初始化。这一篇,继续分析Repository是如何被实例化的。
Repository实例化
通过手动的调用Spring容器的getBean()或者对应的Bean作为其他Bean的属性被赋值的时候,都会对对应的Bean进行实例化。实例化的入口在AbstractBeanFactory.getBean()方法。
AbstractBeanFactory核心代码如下:
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
throws BeansException {
return doGetBean(name, requiredType, args, false);
}
/**
* 返回一个实例
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 获取对应的beanName,如果bean对象实现FactoryBean接口,name会变成&beanName,另外如果存在别名,也需要进行转换
// 会分析是否 以 & 从而为获取beanfactory 实例
String beanName = transformedBeanName(name);
// 定义一个对象,用来存放将来返回出来的bean
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 提前检查单例缓冲中是否有手动注册的单例对象
/**
* 一个bean被put到单例池的渠道有很多;除了spring容器初始化—扫描类----实例化-----put到容器这条线之外还有很多方法可以把一个对象put到单例池
* 举例说明实现方式:
* 1、new AnnotationConfigApplicationContenxt()对象ac,先不指定配置类
* 2、调用ac.getBeanFactory().registerSingleton("xx", a),即将a对象添加到单例池中
* 3、调用ac.register(App.class),添加配置类
* 4、调用ac.refresh(),执行refresh()时,在初始化时会扫描到A,此时a对象已经在单例池里了,所以需要有此判断
*/
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 返回对象的实例,当实现了FactoryBean接口的对象,需要获取具体的对象的时候需要此方法来进行获取
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 当对象都是单例的时候会尝试解决循环依赖的问题,但是原型模式下如果存在循环依赖的情况就直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
.
// 获取父类容器
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName,那么就尝试从父容器中获取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
//获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
//调用父工厂的doGetBean方法,递归调用当前方法
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {//如果有创建bean实例时要使用的参数
// Delegation to parent with explicit args.
// 使用父工厂获取该bean对象带参数获取对象
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 如果不是做类型检查,那么表示要创建bean,此处在集合中做一个标记
if (!typeCheckOnly) {
// 将其加入到 alreadyCreated中,说明正在创建。bean从 mergedBeanDefinitions 中暂时去除,以免再次创建
markBeanAsCreated(beanName);
}
try {
// 此处做了BeanDefinition对象的转换,当从xml文件中加载beanDefinition对象的时候,封装的对象是GenericBeanDefinition,
// 此处要做类型转换,如果是子类bean的话,会合并父类的相关属性
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 判断当前bean 类,是否为抽象类,是就报错
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 如果存在依赖的bean的话,那么则优先实例化依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 如果存在依赖,则需要递归实例化依赖的bean
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册各个bean的依赖关系,方便进行销毁
registerDependentBean(dep, beanName);
try {
// 优先获取 dependon的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 创建bean的实例对象
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
// 包装一层
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 原型模式的bean对象创建
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
// 原型模式,即每次都创建
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
// 包装
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
// 调用scope.get,而还是由createBean去创建bean
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 如果Bean不是工厂,不要让调用代码尝试取消对工厂的引用
// 判断是否为工厂引用。通过name是否以'&'开头来判断,是的话为FactoryBean
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}
// 如果不是工厂实例,直接返回。除非调用者确实需要对工厂的引用,也直接返回
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
// 从工厂bean中获取bean对象
Object object = null;
if (mbd == null) {
//从FactoryBean获得的对象缓存集中获取beanName对应的Bean对象
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 如果对象是单例,则从FactoryBean缓存中获得对象
// 如果mbd为null,且该bean的mbd在缓存中,则从缓存中获取mbd
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否是'synthetic'标记:mbd不为null && 返回此bean定义是否是"synthetic"
// 【一般只有AOP相关的pointCut配置或者Advice配置才会将 synthetic设置为true】
boolean synthetic = (mbd != null && mbd.isSynthetic());
//从BeanFactory对象中获取管理的对象.如果不是synthetic会对其对象进行该工厂的后置处理
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
}
1.1 doGetBean()方法的核心逻辑是:
1.1.1 从单例池ConcurrentHashMap中通过beanName获取对应的对象bean实例,如果有,则调用getObjectForBeanInstance()返回;
1.1.2 如果没有,且有父Bean工厂,从父Bean工厂查找,递归调用doGetBean()方法;
1.1.3 否则获取beanName对应的RootBeanDefinition对象,该对象是基于beanName的BeanDefinition对象创建的;
1.1.4 调用createBean()创建bean实例,如果bean是单例的,会添加到单例池中。然后调用getObjectForBeanInstance()返回;
1.2 getObjectForBeanInstance()方法
上面的1.1.1和1.1.4最后都会调用getObjectForBeanInstance()方法,返回bean是最终实例。返回的实例可能是1.1.4中createBean()返回的实例,也可能是通过createBean()返回的FactoryBean.getObject()生产的实例。方法的核心逻辑如下:
1.2.1 如果不是FactoryBean,或者beanName不是"&"开头的,直接返回对应的bean实例;
1.2.2 否则的话,说明当前bean对应的bean实例是一个FactoryBean工厂bean【专门生产bean的工厂】,最后会执行FactoryBean的getObject()获得实际的bean实例;
1.3 createBean()方法
在上面的1.1.4中会调用createBean()方法创建bean实例。该方法在子类AbstractAutowireCapableBeanFactory中实现。进行验证后,会调用doCreateBean()方法。代码如下:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 锁定class,根据设置的class属性或者根据className来解析class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// 验证及准备覆盖的方法
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 给BeanPostProcessors一个机会来返回代理来替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 从factoryBean实例缓存中移除当前bean定义信息
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 根据执行bean使用对应的策略创建实例对象,仅仅是对象。检查如工厂方法、构造函数主动注入、简单实例化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 可以通过post-processors去修改合并的beanDefinition
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 应用MergedBeanDefinitionPostProcessors
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 判断当前bean是否需要提前曝光:单例&允许循环依赖&当前bean正在创建中,检查循环依赖
/**
* 可以通过修改allowCircularReferences的值设置是否支持循环依赖,设置的方式有多种
* 方式一,通过继承方式
* 自定义一个ApplicationContext类,继承ClassPathXmlApplicationContext,重写customizeBeanFactory()方法
* 在customizeBeanFactory方法中执行如下代码进行属性值的修改
* super.setAllowBeanDefinitionOverriding(true);
* super.setAllowCircularReferences(false);
* super.customizeBeanFactory(beanFactory)
* 方式二,
* 1、new一个不带配置文件的ClassPathXmlApplicationContext或配置类AnnotationConfigApplicationContext对象
* 2、调用ApplicationContext对象的setAllowCircularReferences()方法,修改allowCircularReferences的值
* 3、调用ApplicationContext对象的设置配置文件或配置类的方法
* 4、调用ApplicationContext对象的refresh()方法,完成初始化扫描操作
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
// 对bean属性进行填充,将各个属性注入。其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
populateBean(beanName, mbd, instanceWrapper);
// 执行初始化逻辑【主要执行各种生命周期回调方法以及AOP等】
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 注册bean销毁的监听
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
}
1.3.1 resolveBeanClass()方法
createBean()方法调用resolveBeanClass()方法,resolveBeanClass() 会调用doResolveBeanClass()。在该方法中,会从RootBeanDefinition中获取beanClass,返回beanClass的Class对象。
在上一篇
提到,Repository的BeanDefinition中对应的beanClass为"org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean"字符串,获得的Class为JpaRepositoryFactoryBean.class。
1.3.2 doCreateBean()方法
1.3.2.1 执行createBeanInstance()方法,根据执行bean使用对应的策略创建实例对象,仅仅是对象。检查如工厂方法、构造函数主动注入、简单实例化;
1.3.2.2 执行applyMergedBeanDefinitionPostProcessors(),循环遍历实现MergedBeanDefinitionPostProcessor接口的后置处理器,执行后置处理;
1.3.2.3 执行populateBean(),对bean属性进行填充,注入各个属性;
1.3.2.4 执行initializeBean(),执行初始化逻辑;其中一个初始化是执行InitializingBean.afterPropertiesSet();
在createBean()中根据BeanDefinition中的beanClass,创建一个bean的实例对象,然后调用1.2中的getObjectForBeanInstance()方法,
JpaRepositoryFactoryBean
对于Repository来说,通过1.3.2.1创建的实例为1.3.1中说的JpaRepositoryFactoryBean对象,该对象实现了InitializingBean接口,在1.3.2.4中,会执行InitializingBean.afterPropertiesSet()方法。该方法会执行父类RepositoryFactoryBeanSupport的.afterPropertiesSet()方法。
public abstract class RepositoryFactoryBeanSupport<T extends Repository<S, ID>, S, ID>
implements InitializingBean, RepositoryFactoryInformation<S, ID>, FactoryBean<T>, BeanClassLoaderAware,
BeanFactoryAware, ApplicationEventPublisherAware {
public void afterPropertiesSet() {
// 创建一个Repository工厂,TransactionalRepositoryFactoryBeanSupport对象
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);
// 执行工厂的getRepository()方法,创建一个代理的Repository对象
this.repository = Lazy.of(() -> this.factory.getRepository(repositoryInterface, repositoryFragmentsToUse));
// Make sure the aggregate root type is present in the MappingContext (e.g. for auditing)
this.mappingContext.ifPresent(it -> it.getPersistentEntity(repositoryMetadata.getDomainType()));
if (!lazyInit) {
this.repository.get();
}
}
}
在该方法中,调用factory.getRepository()获取Repository对象。实现在RepositoryFactorySupport类。代码如下:
public abstract class RepositoryFactorySupport implements BeanClassLoaderAware, BeanFactoryAware {
/**
* 返回给定接口的存储库实例,该实例由为自定义逻辑提供实现逻辑的实例支持。
*/
@SuppressWarnings({ "unchecked" })
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");
ApplicationStartup applicationStartup = getStartup();
StartupStep repositoryInit = onEvent(applicationStartup, "spring.data.repository.init", repositoryInterface);
repositoryBaseClass.ifPresent(it -> repositoryInit.tag("baseClass", it.getName()));
StartupStep repositoryMetadataStep = onEvent(applicationStartup, "spring.data.repository.metadata",
repositoryInterface);
// 获取repository元数据,包括Repository<T, ID>中的T类型、ID类型、接口类型(如GoodsRepository)等
RepositoryMetadata metadata = getRepositoryMetadata(repositoryInterface);
repositoryMetadataStep.end();
StartupStep repositoryCompositionStep = onEvent(applicationStartup, "spring.data.repository.composition",
repositoryInterface);
repositoryCompositionStep.tag("fragment.count", String.valueOf(fragments.size()));
// 获取
RepositoryComposition composition = getRepositoryComposition(metadata, fragments);
// 获取Repository信息,getRepositoryInformation()返回一个RepositoryInformation对象。
// 如子类JpaRepositoryFactory,指定baseClass为SimpleJpaRepository.class
RepositoryInformation information = getRepositoryInformation(metadata, composition);
repositoryCompositionStep.tag("fragments", () -> {
StringBuilder fragmentsTag = new StringBuilder();
for (RepositoryFragment<?> fragment : composition.getFragments()) {
if (fragmentsTag.length() > 0) {
fragmentsTag.append(";");
}
fragmentsTag.append(fragment.getSignatureContributor().getName());
fragmentsTag.append(fragment.getImplementation().map(it -> ":" + it.getClass().getName()).orElse(""));
}
return fragmentsTag.toString();
});
repositoryCompositionStep.end();
StartupStep repositoryTargetStep = onEvent(applicationStartup, "spring.data.repository.target",
repositoryInterface);
// 获取目标Repository对象,SimpleJpaRepository对象
Object target = getTargetRepository(information);
repositoryTargetStep.tag("target", target.getClass().getName());
repositoryTargetStep.end();
RepositoryComposition compositionToUse = composition.append(RepositoryFragment.implemented(target));
validate(information, compositionToUse);
// Create proxy
// 创建代理对象
StartupStep repositoryProxyStep = onEvent(applicationStartup, "spring.data.repository.proxy", repositoryInterface);
ProxyFactory result = new ProxyFactory();
result.setTarget(target);
// 代理对象实现的接口
result.setInterfaces(repositoryInterface, Repository.class, TransactionalProxy.class);
if (MethodInvocationValidator.supports(repositoryInterface)) {
result.addAdvice(new MethodInvocationValidator());
}
// 添加界面
result.addAdvisor(ExposeInvocationInterceptor.ADVISOR);
if (!postProcessors.isEmpty()) {
StartupStep repositoryPostprocessorsStep = onEvent(applicationStartup, "spring.data.repository.postprocessors",
repositoryInterface);
// 执行后置处理
// CrudMethodMetadataPostProcessor
// TransactionalRepositoryProxyPostProcessor
// JpaRepositoryFactory构造方法中加入的内部处理器,
// 添加SurroundingTransactionDetectorMethodInterceptor,记录是否处理状态
// PersistenceExceptionTranslationRepositoryProxyPostProcessor
// EventPublishingRepositoryProxyPostProcessor
postProcessors.forEach(processor -> {
StartupStep singlePostProcessor = onEvent(applicationStartup, "spring.data.repository.postprocessor",
repositoryInterface);
singlePostProcessor.tag("type", processor.getClass().getName());
processor.postProcess(result, information);
singlePostProcessor.end();
});
repositoryPostprocessorsStep.end();
}
if (DefaultMethodInvokingMethodInterceptor.hasDefaultMethods(repositoryInterface)) {
// 添加DefaultMethodInvokingMethodInterceptor拦截器
result.addAdvice(new DefaultMethodInvokingMethodInterceptor());
}
Optional<QueryLookupStrategy> queryLookupStrategy = getQueryLookupStrategy(queryLookupStrategyKey,
evaluationContextProvider);
// 添加QueryExecutorMethodInterceptor拦截器
result.addAdvice(new QueryExecutorMethodInterceptor(information, getProjectionFactory(), queryLookupStrategy,
namedQueries, queryPostProcessors, methodInvocationListeners));
// 添加ImplementationMethodExecutionInterceptor拦截器
result.addAdvice(
new ImplementationMethodExecutionInterceptor(information, compositionToUse, methodInvocationListeners));
T repository = (T) result.getProxy(classLoader);
repositoryProxyStep.end();
repositoryInit.end();
if (logger.isDebugEnabled()) {
logger
.debug(LogMessage.format("Finished creation of repository instance for %s.",
repositoryInterface.getName()));
}
return repository;
}
}
在该方法中,使用ProxyFactory代理,代理实现了自定义的Repository接口、Repository以及TransactionProxy接口,且代理的target为SimpleJpaRepository对象。添加了MethodInvocationValidator、ExposeInvocationInterceptor、DefaultMethodInvokingMethodInterceptor、QueryExecutorMethodInterceptor、ImplementationMethodExecutionInterceptor拦截器。
小结
限于篇幅,本篇就分享到这里,这里做一个小结:
1)在Spring中,会执行AbstractBeanFactory.doGetBean()方法,先从Repository的BeanDefinition中,获取beanClass,为JpaRepositoryFactoryBean类名,然后创建JpaRepositoryFactoryBean对象。执行afterPropertiesSet()方法,完成初始化;
2)在JpaRepositoryFactoryBean的afterPropertiesSet()初始化方法中,会调用RepositoryFactorySupport.getRepository()方法。该方法通过代理的的方式,创建一个实现了自定义的Repository接口、Repository以及TransactionProxy接口,且代理的target为SimpleJpaRepository对象。代理的对象保存在repository属性中;
3)在Spring中,执行了JpaRepositoryFactoryBean对象的afterPropertiesSet()初始化之后,会调用AbstractBeanFactory.getObjectForBeanInstance(),从JpaRepositoryFactoryBean工厂bean中执行getObject(),返回创建的代理repository对象;
关于本篇内容你有什么自己的想法或独到见解,欢迎在评论区一起交流探讨下吧。