关于jpa初始化
实体类扫描
@EntityScan(basePackages = { })
来到 EntityScanPackages.Registrar.class
扫描并注册beandefinition
public static void register(BeanDefinitionRegistry registry, Collection<String> packageNames) { if (registry.containsBeanDefinition(BEAN)) {//被提前注册直接添加构造函数即可 BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN); ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues(); constructorArguments.addIndexedArgumentValue(0, addPackageNames(constructorArguments, packageNames)); } else { GenericBeanDefinition beanDefinition = new GenericBeanDefinition();//创建beandefinition beanDefinition.setBeanClass(EntityScanPackages.class);//配置bean class beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, StringUtils.toStringArray(packageNames)); //将package添加为构造函数 beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(BEAN, beanDefinition); } }
来到构造函数也就是bean初始化的过程
EntityScanPackages(String... packageNames) { List<String> packages = new ArrayList<>(); for (String name : packageNames) { if (StringUtils.hasText(name)) { packages.add(name); } } this.packageNames = Collections.unmodifiableList(packages);//返回一个不可被修改的list }
bean被注册完后来到jpa自动配置类 这里默认是有hibernate实现
HibernateJpaConfiguration //数据源 jpa参数 bean工厂 jta事务管理 hibernate参数 数据库连接池信息提供者 hibernate参数改造器等 HibernateJpaConfiguration(DataSource dataSource, JpaProperties jpaProperties, ConfigurableListableBeanFactory beanFactory, ObjectProvider<JtaTransactionManager> jtaTransactionManager, HibernateProperties hibernateProperties, ObjectProvider<Collection<DataSourcePoolMetadataProvider>> metadataProviders, ObjectProvider<SchemaManagementProvider> providers, ObjectProvider<PhysicalNamingStrategy> physicalNamingStrategy, ObjectProvider<ImplicitNamingStrategy> implicitNamingStrategy, }
创建jpa供应商适配器
JpaVendorAdapter 一个spi接口 这里是hibernate提供
PersistenceProvider getPersistenceProvider()//获取持久化提供者 default String getPersistenceProviderRootPackage() {//提供者根路径 这里是org.hibernate return null; } getJpaPropertyMap //获取jpa参数 getEntityManagerFactoryInterface() //获取实体管理工厂接口 class类型
@Bean @ConditionalOnMissingBean public JpaVendorAdapter jpaVendorAdapter() { AbstractJpaVendorAdapter adapter = createJpaVendorAdapter();//new HibernateJpaVendorAdapter();hibernate提供 //.... return adapter; }
创建实体工厂构建器
@Bean @ConditionalOnMissingBean public EntityManagerFactoryBuilder entityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter, ObjectProvider<PersistenceUnitManager> persistenceUnitManager, ObjectProvider<EntityManagerFactoryBuilderCustomizer> customizers) { EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(jpaVendorAdapter, this.properties.getProperties(), persistenceUnitManager.getIfAvailable()); customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); return builder; }
通过构造器创建EntityManagerFactoryBean 实现了FactoryBean接口最终会创建出EntityManagerFactory
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder factoryBuilder) { //获取供应商属性 Map<String, Object> vendorProperties = getVendorProperties(); customizeVendorProperties(vendorProperties); return //配置数据源 实体扫描包 属性 factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan()).properties(vendorProperties) .mappingResources(getMappingResources()).jta(isJta()).build(); }
直接看build方法
public LocalContainerEntityManagerFactoryBean build() { //创建出factoryBean先 LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); //配置jpa厂家适配器 entityManagerFactoryBean.setJpaVendorAdapter(EntityManagerFactoryBuilder.this.jpaVendorAdapter); //是否开启jta事务 if (this.jta) { entityManagerFactoryBean.setJtaDataSource(this.dataSource); } else { //配置数据源 entityManagerFactoryBean.setDataSource(this.dataSource); } //配置需要扫描的类 entityManagerFactoryBean.setPackagesToScan(this.packagesToScan); entityManagerFactoryBean.getJpaPropertyMap().putAll(EntityManagerFactoryBuilder.this.jpaProperties); }
初始化 LocalContainerEntityManagerFactoryBean 调用初始化方法 afterPropertiesSet 初始化持久化单元管理 调用链如下
afterPropertiesSet DefaultPersistenceUnitManager preparePersistenceUnitInfos //获取项目classurl通过classLoader获取 配置DataSource readPersistenceUnitInfos //读取相关配置 实体类等 buildDefaultPersistenceUnitInfo //构建持久化单元信息 或有的实体类信息等 scanPackage //扫描配置类 获取到managedClassNames 所有的实体类 获取持久化提供者 这里是hibernate super.afterPropertiesSet buildNativeEntityManagerFactory createNativeEntityManagerFactory//创建连接等 创建EntityManagerFactory 启动数据连接池 连接数据库 为EntityManagerFactory创建代理 用事务和Query类型参数查询 DefaultPersistenceUnitManager用于持久化
@ EnableJpaRepositories 代理查询方法
来到RepositoryBeanDefinitionRegistrarSupport
RepositoryConfigurationDelegate delegate = new RepositoryConfigurationDelegate(configurationSource, resourceLoader, environment); delegate.registerRepositoriesIn(registry, extension); //首先获取所有的配置类 Collection<RepositoryConfiguration<RepositoryConfigurationSource>> configurations = extension .getRepositoryConfigurations(configurationSource, resourceLoader, inMultiStoreMode); //通过获取的配置创建beanDefinition 使用 JpaRepositoryFactoryBean实现 BeanDefinitionBuilder definitionBuilder = builder.build(configuration); //添加属性 事务管理 实体管理 extension.postProcess(definitionBuilder, configurationSource); //通过类名构建beanName String beanName = configurationSource.generateBeanName(beanDefinition); //注册beanDefinition registry.registerBeanDefinition(beanName, beanDefinition);
//获取所有的repositoryCOnfiguration
public <T extends RepositoryConfigurationSource> Collection<RepositoryConfiguration<T>> getRepositoryConfigurations( T configSource, ResourceLoader loader, boolean strictMatchesOnly) { Set<RepositoryConfiguration<T>> result = new HashSet<>(); for (BeanDefinition candidate : configSource.getCandidates(loader)) { RepositoryConfiguration<T> configuration = getRepositoryConfiguration(candidate, configSource); Class<?> repositoryInterface = loadRepositoryInterface(configuration, getConfigurationInspectionClassLoader(loader));//获取到interface return result; }
getCandidates方法用户获取所有被jpa配置的类
RepositoryComponentProvider scanner = new RepositoryComponentProvider(getIncludeFilters(), registry); //这里通过RepositoryComponent扫描所有匹配的类使用filter的方式 构造方法截取如下 // super.addIncludeFilter(new InterfaceTypeFilter(Repository.class)); super.addIncludeFilter(new AnnotationTypeFilter(RepositoryDefinition.class, true, true)); //同时派出NoRepositoryBean注解 addExcludeFilter(new AnnotationTypeFilter(NoRepositoryBean.class)); //所以只需要实现接口即可,不需要标注@Repository注解 scanner.setConsiderNestedRepositoryInterfaces(shouldConsiderNestedRepositories()); scanner.setEnvironment(environment); scanner.setResourceLoader(loader); getExcludeFilters().forEach(it -> scanner.addExcludeFilter(it)); //通过findCandidateComponents获取所有的beanDefinition return Streamable.of(() -> getBasePackages().stream()// .flatMap(it -> scanner.findCandidateComponents(it).stream()));
### jpa查询
jpa查询底层使用的动态代理生成,由hibernate实现
jap 查询代理
首先通过接口被spring的JdkDynamicAopProxy代理
代理对象为SimpleJpaRepository 可以看到当前SimpleJpaRepository被jdk动态代理了,内部实现了一些单表的crud操作
从spring缓存中获取advised 创建MethodInvocation 这里就是springaop的开始了
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); // Proceed to the joinpoint through the interceptor chain. retVal = invocation.proceed();
ReflectiveMethodInvocation#proceed()
SimpleJpaRepositoryif (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {//当前拦截的index是否为左后一个执行完了 那就直接通过SimpleJpaRepository执行方法,它们都实现了JpaRepository return invokeJoinpoint(); } //获取拦截的advice 当前拦截器Index加一 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); //这里是特殊的Advice需要匹配 直接跳过 if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { ... } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); }
第一个拦截器 ExposeInvocationInterceptor
public Object invoke(MethodInvocation mi) throws Throwable { MethodInvocation oldInvocation = invocation.get(); invocation.set(mi);//保存当前的上下文以便后面的拦截器使用 ReflectiveMethodInvocation try { return mi.proceed(); //继续调用下一层 } finally { invocation.set(oldInvocation); } }
第二个拦截器 CrudMethodMetadataPostProcessor
对curd方法元数据进行处理 Method method = invocation.getMethod(); if (!implementations.contains(method)) {//是否为接口自带实现方法 return invocation.proceed(); }
第三个拦截器 PersistenceExceptionTranslationInterceptor
持久层异常处理
第四个 TransactionInterceptor
事务拦截器 用于对事务的处理 获取事务管理器与事务属性 判断是否开启事务处理
第5个拦截器 DefaultMethodInvokingMethodInterceptor
对默认方法进行处理 if (!method.isDefault()) { return invocation.proceed(); }
第6个拦截器 QueryExecutorMethodInterceptor
查询执行器方法 Method method = invocation.getMethod(); QueryExecutionConverters.ExecutionAdapter executionAdapter = QueryExecutionConverters //比如list 根据返回类型获取对应的执行器 .getExecutionAdapter(method.getReturnType()); if (executionAdapter == null) { return resultHandler.postProcessInvocationResult(doInvoke(invocation), method);//对结果进行处理 }
doInvok方法
private Object doInvoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); if (hasQueryFor(method)) {//是否为查询方法 QueryMethodInvoker invocationMetadata = invocationMetadataCache.get(method); if (invocationMetadata == null) { invocationMetadata = new QueryMethodInvoker(method);//创建方法执行器 invocationMetadataCache.put(method, invocationMetadata); } RepositoryQuery repositoryQuery = queries.get(method); return invocationMetadata.invoke(repositoryQuery, invocation.getArguments()); } return invocation.proceed(); }
获取执行器执行方法