栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Data Jpa的源码探究

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Data Jpa的源码探究

Spring Data Jpa的源码探究 Spring Data Jpa的自动配置

Spring Data JPA的自动配置类,在一定的条件下开启

1.JpaRepositoriesAutoConfiguration

@Configuration(proxyBeanMethods = false)   
@ConditionalOnBean(DataSource.class)           //判断是否配置了数据源
@ConditionalOnClass(JpaRepository.class)       //判断是否配置了JpaRepository
@ConditionalOnMissingBean({ JpaRepositoryFactoryBean.class, JpaRepositoryConfigExtension.class })
@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "enabled", havingValue = "true",
		matchIfMissing = true)                //判断是否在application.properties里是否开启了此enabled
@import(JpaRepositoriesRegistrar.class)        //持久层注册器
@AutoConfigureAfter({ HibernateJpaAutoConfiguration.class, TaskExecutionAutoConfiguration.class })
public class JpaRepositoriesAutoConfiguration {
       //-------------------------省略里面的启动代码,(其实是看不懂,先不管)

}
Spring Data Jpa提供的各种Repository接口
Repository
CrudRepository
PagingAndSortingRepository
JpaRepository
以上四种Repository接口是依次继承的,并在JpaRepository接口中最完善
Repository

Repository源码,Repository是这四个Repository中作为基类的接口,需要提供T,ID两个泛型

@Indexed
public interface Repository {

}

使用方法:在持久层接口中继承此接口即可。

​ 在持久层接口中再按一定的规则编写接口方法即可,

​ Spring启动扫描后会自动为你定义的方法生成实现类(前提是方法命名正确,且使用@Repository注解)

在此不详细介绍方法命名规则,

我直接给出官方文档的方法命名规则的链接

Spring Data JPA - Reference documentation

另外也有很多人做出了分享,可以Repository方法命名规则即可

CrudRepository

顾名思义:增删改查Repository,在其中为我们定义了一些我们要用到的基础的增删改查方法

源码:

@NoRepositoryBean
public interface CrudRepository extends Repository {

	//保存一个实体Entity对象,(可以是该对象的子类,因为有可能是继承映射的关系)
	 S save(S entity);

	//通过泛型的迭代器来保存一个集合类型的实体 例 :saveAll(new ArrayList().iterator())
	 Iterable saveAll(Iterable entities);
    
    //很简单,通过ID查询
	Optional findById(ID id);

	//通过ID判断
	boolean existsById(ID id);

	//查找所有实体类
	Iterable findAll();

	//寻找指定ID集合的对象
	Iterable findAllById(Iterable ids);

	//计算实体个数,(很简单,只需要一个简单的聚合函数就可以办到)
	long count();

	//通过指定ID删除
	void deleteById(ID id);

	//传入实体对象进行删除
	void delete(T entity);

	//根据传入的ID集合进行删除
	void deleteAllById(Iterable ids);

	
	void deleteAll(Iterable entities);

	
	void deleteAll();
}

为我们定义了一些通用的持久层方法,很实用

PagingAndSortingRepository

分页和排序repository,在CRUDrepository的基础上进一步提供了分页和排序的功能

前言:

JPA的排序源于Hibernate的排序,

可以在hibernate的mapping的集合属性中设置order-by关键字

也有@OrderBy注解可以进行排序

在典型的Hibernate的Query查询中

Query对象有.setFristResult(int arg0)和setMaxResult方法,

Query query = entityManager.createQuery("from article").setFirstResult(arg0);
		query.setMaxResults(arg0)
//FirstResult无疑是开始编号
//MaxResults无疑是返回结果的数量(页的记录数)
//通过这两个方法就可以完成数据库的分页操作,(sql语句的数据库分页,不同于mybatis的内存分页,个人认为此方面Hibernate更加优秀)

源码:

@NoRepositoryBean
public interface PagingAndSortingRepository extends CrudRepository {

	//传入一个实现sort实例进行全部查找,(sort是一个类)
	Iterable findAll(Sort sort);

	//通过实现了pageable接口的对象进行查找
	Page findAll(Pageable pageable);
}

官方文档链接,(这里官网的示例展示的比较简单,需要自行查看,pageable源码)

Spring Data JPA - Reference documentation

Sort工具类(来自springData的domain包)

Sort对象是一个典型的工具类,用于描述JPA(同样可用于SpringData的其他框架)的排序规则

使用方法:不需要自定义类去继承Sort,Sort类自带静态方法可以指定排序规则

Sort源码:

public class Sort implements Streamable, Serializable {

	private static final long serialVersionUID = 5737186511678863905L;

	private static final Sort UNSORTED = Sort.by(new Order[0]);  
    
    //静态常量unsorted代表未排序

	public static final Direction DEFAULT_DIRECTION = Direction.ASC;  
    
    //默认排序方向ASC顺序,可改为DESC逆序

    //静态内部类Order集合
	private final List orders;

	protected Sort(List orders) {
		this.orders = orders;
	}

	//私有构造函数,通过Direction对象和属性集合排序
	private Sort(Direction direction, List properties) {

		if (properties == null || properties.isEmpty()) {
			throw new IllegalArgumentException("You have to provide at least one property to sort by!");
		}

        //这个操作使用了流操作,将String的集合转化为Order集合,很妙!
		this.orders = properties.stream() //
				.map(it -> new Order(direction, it)) //
				.collect(Collectors.toList());
	}

	//通过Entity的属性进行排序,返回一个Sort对象
	public static Sort by(String... properties) {

		Assert.notNull(properties, "Properties must not be null!");

		return properties.length == 0 //
				? Sort.unsorted() //
				: new Sort(DEFAULT_DIRECTION, Arrays.asList(properties));
	}

	//根据Order集合进行排序,这里的Order是Sort类的静态内部类,下面有其定义
	public static Sort by(List orders) {

		Assert.notNull(orders, "Orders must not be null!");

		return orders.isEmpty() ? Sort.unsorted() : new Sort(orders);
	}

	
	public static Sort by(Order... orders) {

		Assert.notNull(orders, "Orders must not be null!");

		return new Sort(Arrays.asList(orders));
	}

	
	public static Sort by(Direction direction, String... properties) {

		Assert.notNull(direction, "Direction must not be null!");
		Assert.notNull(properties, "Properties must not be null!");
		Assert.isTrue(properties.length > 0, "At least one property must be given!");

		return Sort.by(Arrays.stream(properties)//
				.map(it -> new Order(direction, it))//
				.collect(Collectors.toList()));
	}

	
	public static  TypedSort sort(Class type) {
		return new TypedSort<>(type);
	}

	//静态方法,返回不排序的常量
	public static Sort unsorted() {
		return UNSORTED;
	}

	//排序接口呈倒叙
	public Sort descending() {
		return withDirection(Direction.DESC);
	}

	//排序接口呈先序
	public Sort ascending() {
		return withDirection(Direction.ASC);
	}

	public boolean isSorted() {
		return !isEmpty();
	}

	@Override
	public boolean isEmpty() {
		return orders.isEmpty();
	}

	public boolean isUnsorted() {
		return !isSorted();
	}

	//排序条件的叠加
	public Sort and(Sort sort) {

		Assert.notNull(sort, "Sort must not be null!");

		ArrayList these = new ArrayList<>(this.toList());

		for (Order order : sort) {
			these.add(order);
		}

		return Sort.by(these);
	}

	//获取属性的Order
	@Nullable
	public Order getOrderFor(String property) {

		for (Order order : this) {
			if (order.getProperty().equals(property)) {
				return order;
			}
		}

		return null;
	}

	//获取Order集合的迭代器
	public Iterator iterator() {
		return this.orders.iterator();
	}

	//重写了equals方法
	@Override
	public boolean equals(@Nullable Object obj) {

		if (this == obj) {
			return true;
		}

		if (!(obj instanceof Sort)) {
			return false;
		}

		Sort that = (Sort) obj;

		return toList().equals(that.toList());
	}

	//重写了hashCode方法
	@Override
	public int hashCode() {

		int result = 17;
		result = 31 * result + orders.hashCode();
		return result;
	}

	//重写了toString
	@Override
	public String toString() {
		return isEmpty() ? "UNSORTED" : StringUtils.collectionToCommaDelimitedString(orders);
	}

	//私有方法,在前面的方法中被调用
	private Sort withDirection(Direction direction) {

		return Sort.by(stream().map(it -> new Order(direction, it.getProperty())).collect(Collectors.toList()));
	}

	
	public static enum Direction {

		ASC, DESC;

		//是否为升序
		public boolean isAscending() {
			return this.equals(ASC);
		}

		//是否为倒叙
		public boolean isDescending() {
			return this.equals(DESC);
		}

		//将字符串转化为ASC或者DESC,否则跑个非法参数异常
		public static Direction fromString(String value) {

			try {
				return Direction.valueOf(value.toUpperCase(Locale.US));
			} catch (Exception e) {
				throw new IllegalArgumentException(String.format(
						"Invalid value '%s' for orders given! Has to be either 'desc' or 'asc' (case insensitive).", value), e);
			}
		}

		
		public static Optional fromOptionalString(String value) {

			try {
				return Optional.of(fromString(value));
			} catch (IllegalArgumentException e) {
				return Optional.empty();
			}
		}
	}

	
	public static enum NullHandling {

		NATIVE,

		NULLS_FIRST,

		NULLS_LAST;
	}

	//内部类Order
	public static class Order implements Serializable {

		private static final long serialVersionUID = 1522511010900108987L;
		private static final boolean DEFAULT_IGNORE_CASE = false;
		private static final NullHandling DEFAULT_NULL_HANDLING = NullHandling.NATIVE;

		private final Direction direction;  //排序方式
		private final String property;      //Entity属性名
		private final boolean ignoreCase;   //是否忽略大小写
		private final NullHandling nullHandling; //nullhandling对象

		
		public Order(@Nullable Direction direction, String property) {
			this(direction, property, DEFAULT_IGNORE_CASE, DEFAULT_NULL_HANDLING);
		}

		
		public Order(@Nullable Direction direction, String property, NullHandling nullHandlingHint) {
			this(direction, property, DEFAULT_IGNORE_CASE, nullHandlingHint);
		}

		
		public static Order by(String property) {
			return new Order(DEFAULT_DIRECTION, property);
		}

		
		public static Order asc(String property) {
			return new Order(Direction.ASC, property, DEFAULT_NULL_HANDLING);
		}

		public static Order desc(String property) {
			return new Order(Direction.DESC, property, DEFAULT_NULL_HANDLING);
		}

		
		private Order(@Nullable Direction direction, String property, boolean ignoreCase, NullHandling nullHandling) {

			if (!StringUtils.hasText(property)) {
				throw new IllegalArgumentException("Property must not null or empty!");
			}

			this.direction = direction == null ? DEFAULT_DIRECTION : direction;
			this.property = property;
			this.ignoreCase = ignoreCase;
			this.nullHandling = nullHandling;
		}

		
		public Direction getDirection() {
			return direction;
		}

		public String getProperty() {
			return property;
		}

		public boolean isAscending() {
			return this.direction.isAscending();
		}

		public boolean isDescending() {
			return this.direction.isDescending();
		}

		public boolean isIgnoreCase() {
			return ignoreCase;
		}

		public Order with(Direction direction) {
			return new Order(direction, this.property, this.ignoreCase, this.nullHandling);
		}

		public Order withProperty(String property) {
			return new Order(this.direction, property, this.ignoreCase, this.nullHandling);
		}

		public Sort withProperties(String... properties) {
			return Sort.by(this.direction, properties);
		}

		public Order ignoreCase() {
			return new Order(direction, property, true, nullHandling);
		}

		public Order with(NullHandling nullHandling) {
			return new Order(direction, this.property, ignoreCase, nullHandling);
		}

		public Order nullsFirst() {
			return with(NullHandling.NULLS_FIRST);
		}

		public Order nullsLast() {
			return with(NullHandling.NULLS_LAST);
		}

		public Order nullsNative() {
			return with(NullHandling.NATIVE);
		}

		public NullHandling getNullHandling() {
			return nullHandling;
		}

		@Override
		public int hashCode() {

			int result = 17;

			result = 31 * result + direction.hashCode();
			result = 31 * result + property.hashCode();
			result = 31 * result + (ignoreCase ? 1 : 0);
			result = 31 * result + nullHandling.hashCode();

			return result;
		}

		@Override
		public boolean equals(@Nullable Object obj) {

			if (this == obj) {
				return true;
			}

			if (!(obj instanceof Order)) {
				return false;
			}

			Order that = (Order) obj;

			return this.direction.equals(that.direction) && this.property.equals(that.property)
					&& this.ignoreCase == that.ignoreCase && this.nullHandling.equals(that.nullHandling);
		}

		@Override
		public String toString() {

			String result = String.format("%s: %s", property, direction);

			if (!NullHandling.NATIVE.equals(nullHandling)) {
				result += ", " + nullHandling;
			}

			if (ignoreCase) {
				result += ", ignoring case";
			}

			return result;
		}
	}

	//官网上说是新特性,为类型安全的Sort
    //https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.paging-and-sorting
	public static class TypedSort extends Sort {

		private static final long serialVersionUID = -3550403511206745880L;

		private final Recorded recorded;

		private TypedSort(Class type) {
			this(MethodInvocationRecorder.forProxyOf(type));
		}

		private TypedSort(Recorded recorded) {

			super(Collections.emptyList());
			this.recorded = recorded;
		}

		public  TypedSort by(Function property) {
			return new TypedSort<>(recorded.record(property));
		}

		public  TypedSort by(Recorded.ToCollectionConverter collectionProperty) {
			return new TypedSort<>(recorded.record(collectionProperty));
		}

		public  TypedSort by(Recorded.ToMapConverter mapProperty) {
			return new TypedSort<>(recorded.record(mapProperty));
		}

		@Override
		public Sort ascending() {
			return withDirection(Sort::ascending);
		}

		@Override
		public Sort descending() {
			return withDirection(Sort::descending);
		}

		private Sort withDirection(Function direction) {

			return recorded.getPropertyPath() //
					.map(Sort::by) //
					.map(direction) //
					.orElseGet(Sort::unsorted);
		}

		
		@Override
		public Iterator iterator() {

			return recorded.getPropertyPath() //
					.map(Order::by) //
					.map(Collections::singleton) //
					.orElseGet(Collections::emptySet).iterator();
		}

		@Override
		public boolean isEmpty() {
			return !recorded.getPropertyPath().isPresent();
		}

		
		@Override
		public String toString() {

			return recorded.getPropertyPath() //
					.map(Sort::by) //
					.orElseGet(Sort::unsorted) //
					.toString();
		}
	}
}

Sort类型的使用

Sort (Spring Data Core 2.5.5 API)

参考文章

(1条消息) Spring data jpa sort多属性排序问题_MOON-CSDN博客

Pageable接口:(来自springData的domain包)
public interface Pageable {

	//不分页
	static Pageable unpaged() {
		return Unpaged.INSTANCE;
	}

	//静态方法,返回Pageable实例,PageRequest是其实现类
	static Pageable ofSize(int pageSize) {
		return PageRequest.of(0, pageSize);
	}

	//是否分页
	default boolean isPaged() {
		return true;
	}

	//是否没分页
	default boolean isUnpaged() {
		return !isPaged();
	}

	//获取页数
	int getPageNumber();

	//获取页的内容数量(page的Size)
	int getPageSize();

	
	long getOffset();

	//获取分页的排序对象
	Sort getSort();

	//上述方法的默认实现
	default Sort getSortOr(Sort sort) {

		Assert.notNull(sort, "Fallback Sort must not be null!");

		return getSort().isSorted() ? getSort() : sort;
	}

	//获取下一页的实例
	Pageable next();

	//前一页或第一页
	Pageable previousOrFirst();

	//获取第一页
	Pageable first();

	//获取指定页数的数据
	Pageable withPage(int pageNumber);

	//是否有前一页
	boolean hasPrevious();

	
	default Optional toOptional() {
		return isUnpaged() ? Optional.empty() : Optional.of(this);
	}

}

实现类PageRequest,

public class PageRequest extends AbstractPageRequest { //他基础的AbstractPageRequest实现类Pageable接口

	private static final long serialVersionUID = -4541509938956089562L;

	private final Sort sort;

	
	protected PageRequest(int page, int size, Sort sort) {

		super(page, size);

		Assert.notNull(sort, "Sort must not be null!");

		this.sort = sort;
	}

	//默认不排序的分页,
    //静态方法,返回PageRequest实例
	public static PageRequest of(int page, int size) {
		return of(page, size, Sort.unsorted());
	}

	//传入Sort对象进行分页
    //静态方法,返回PageRequest实例
	public static PageRequest of(int page, int size, Sort sort) {
		return new PageRequest(page, size, sort);
	}

	//还是使用Sort类的方法进行排序,只是形参有点区别
	public static PageRequest of(int page, int size, Direction direction, String... properties) {
		return of(page, size, Sort.by(direction, properties));
	}

	
	public static PageRequest ofSize(int pageSize) {
		return PageRequest.of(0, pageSize);
	}

	
	public Sort getSort() {
		return sort;
	}

    //下面是Pageable接口的具体实现
	
	@Override
	public PageRequest next() {
		return new PageRequest(getPageNumber() + 1, getPageSize(), getSort());
	}

	
	@Override
	public PageRequest previous() {
		return getPageNumber() == 0 ? this : new PageRequest(getPageNumber() - 1, getPageSize(), getSort());
	}

	
	@Override
	public PageRequest first() {
		return new PageRequest(0, getPageSize(), getSort());
	}

	
	@Override
	public boolean equals(@Nullable Object obj) {

		if (this == obj) {
			return true;
		}

		if (!(obj instanceof PageRequest)) {
			return false;
		}

		PageRequest that = (PageRequest) obj;

		return super.equals(that) && this.sort.equals(that.sort);
	}

	
	@Override
	public PageRequest withPage(int pageNumber) {
		return new PageRequest(pageNumber, getPageSize(), getSort());
	}

	
	public PageRequest withSort(Direction direction, String... properties) {
		return new PageRequest(getPageNumber(), getPageSize(), Sort.by(direction, properties));
	}

	
	public PageRequest withSort(Sort sort) {
		return new PageRequest(getPageNumber(), getPageSize(), sort);
	}

	
	@Override
	public int hashCode() {
		return 31 * super.hashCode() + sort.hashCode();
	}

	
	@Override
	public String toString() {
		return String.format("Page request [number: %d, size %d, sort: %s]", getPageNumber(), getPageSize(), sort);
	}

}

然后再看一眼AbstractPageRequest

public abstract class AbstractPageRequest implements Pageable, Serializable {

	private static final long serialVersionUID = 1232825578694716871L;

	private final int page;
	private final int size;

	public AbstractPageRequest(int page, int size) {

		if (page < 0) {
			throw new IllegalArgumentException("Page index must not be less than zero!");
		}

		if (size < 1) {
			throw new IllegalArgumentException("Page size must not be less than one!");
		}

		this.page = page;
		this.size = size;
	}

	
	public int getPageSize() {
		return size;
	}

	
	public int getPageNumber() {
		return page;
	}

	
	public long getOffset() {
		return (long) page * (long) size;
	}

	
	public boolean hasPrevious() {
		return page > 0;
	}

	
	public Pageable previousOrFirst() {
		return hasPrevious() ? previous() : first();
	}

	
	public abstract Pageable next();

	
	public abstract Pageable previous();

	
	public abstract Pageable first();

	@Override
	public int hashCode() {

		final int prime = 31;
		int result = 1;

		result = prime * result + page;
		result = prime * result + size;

		return result;
	}

	
	@Override
	public boolean equals(Object obj) {

		if (this == obj) {
			return true;
		}

		if (obj == null || getClass() != obj.getClass()) {
			return false;
		}

		AbstractPageRequest other = (AbstractPageRequest) obj;
		return this.page == other.page && this.size == other.size;
	}
}
JpaRepository
@NoRepositoryBean
public interface JpaRepository extends PagingAndSortingRepository, QueryByExampleExecutor {
                                            //继承了P&S Repository,还有Example查询接口                                     
	
	@Override
	List findAll();

	
	@Override
	List findAll(Sort sort);

	
	@Override
	List findAllById(Iterable ids);

	
	@Override
	 List saveAll(Iterable entities);

	void flush();

	
	 S saveAndFlush(S entity);

	
	 List saveAllAndFlush(Iterable entities);

	
	@Deprecated
	default void deleteInBatch(Iterable entities){deleteAllInBatch(entities);}

	
	void deleteAllInBatch(Iterable entities);


	
	void deleteAllByIdInBatch(Iterable ids);

	
	void deleteAllInBatch();

	
	@Deprecated
	T getOne(ID id);

	
	T getById(ID id);

	
	@Override
	 List findAll(Example example);

	
	@Override
	 List findAll(Example example, Sort sort);
}

一路继承到JpaRepository已经有很多方法提供了,在它的基础上还继承了Example查询的接口QueryByExampleExecutor

public interface QueryByExampleExecutor {

	
	 Optional findOne(Example example);

	
	 Iterable findAll(Example example);

	
	 Iterable findAll(Example example, Sort sort);

	
	 Page findAll(Example example, Pageable pageable);

	
	 long count(Example example);

	
	 boolean exists(Example example);
}

(Example查询很像Hibernate提供的QBC查询(QueryByCritria),QBC提供一个Critria表示条件,可以通过Restriction的静态方法获取实例)

而Example则要通过构造泛型对象进行查询,

个人感觉:既然在Hibernate中就不是很推荐使用QBC,那这个Example查询我也不是很推荐,能用HQL或JPQL表达清楚的查询为什 么要包装成对象?

SpringDataJpa提供的Repository实现类SimpleJpaRepository

在扫描了我们自定义的Repository接口后,Spring会根据我们的配置信息创建SimpleJpaRepository对象用来完成需要的工作

@Repository
@Transactional(readonly = true)
public class SimpleJpaRepository implements JpaRepositoryImplementation {
                                                  //该接口继承了JpaRepository接口
	private static final String ID_MUST_NOT_BE_NULL = "The given id must not be null!";

	private final JpaEntityInformation entityInformation;  //实体类信息
	private final EntityManager em;                              //重要:Session,过去的Hibernate原生用法,我们要使用session来完成大多数的操作,现在Spring Data 默认为我们生成这个持久层Repository对象(在JPA里Session叫EntityManage.SessionFactory叫EntityManageFactory)
	private final PersistenceProvider provider;

	private @Nullable CrudMethodmetadata metadata;              //增删改查方法信息
    
	private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;  //字符逃逸,转译掉特殊字符,防止SQL注入

	//构造方法
	public SimpleJpaRepository(JpaEntityInformation entityInformation, EntityManager entityManager) {

		Assert.notNull(entityInformation, "JpaEntityInformation must not be null!");
		Assert.notNull(entityManager, "EntityManager must not be null!");

		this.entityInformation = entityInformation;
		this.em = entityManager;
		this.provider = PersistenceProvider.fromEntityManager(entityManager);
	}

	//构造方法重载
	public SimpleJpaRepository(Class domainClass, EntityManager em) {
		this(JpaEntityInformationSupport.getEntityInformation(domainClass, em), em);
	}

	
	//。。。。。。。。。。。。。。。。。。。。。。。。。。此处省略1000行,下面大多是一些方法实现
}
RepositoryFactory持久层工厂

持久层工厂,顾名思义,即以工厂模式生产Repository对象即上述的SimpleJpaRepository

看看JpaRepositoryFactoryBean

public class JpaRepositoryFactoryBean, S, ID>
		extends TransactionalRepositoryFactoryBeanSupport {

	private @Nullable EntityManager entityManager;
	private EntityPathResolver entityPathResolver;
	private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
	private JpaQueryMethodFactory queryMethodFactory;

	
	public JpaRepositoryFactoryBean(Class repositoryInterface) {
		super(repositoryInterface);
	}

	//JPA的注解,从IOC容器的EntityManageFactory里获取EntityManage(Session)
	@PersistenceContext
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	//获取实体类注解生产的mapping内容
	@Override
	public void setMappingContext(MappingContext mappingContext) {
		super.setMappingContext(mappingContext);
	}

	//注入实体类的路径
	@Autowired
	public void setEntityPathResolver(ObjectProvider resolver) {
		this.entityPathResolver = resolver.getIfAvailable(() -> SimpleEntityPathResolver.INSTANCE);
	}

	//注入查询方法工厂
	@Autowired
	public void setQueryMethodFactory(@Nullable JpaQueryMethodFactory factory) {

		if (factory != null) {
			this.queryMethodFactory = factory;
		}
	}

	//创建RepositoryFactory
	@Override
	protected RepositoryFactorySupport doCreateRepositoryFactory() {

		Assert.state(entityManager != null, "EntityManager must not be null!");

		return createRepositoryFactory(entityManager);
	}

	
	protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {

		JpaRepositoryFactory jpaRepositoryFactory = new JpaRepositoryFactory(entityManager);
		jpaRepositoryFactory.setEntityPathResolver(entityPathResolver);
		jpaRepositoryFactory.setEscapeCharacter(escapeCharacter);

		if (queryMethodFactory != null) {
			jpaRepositoryFactory.setQueryMethodFactory(queryMethodFactory);
		}

		return jpaRepositoryFactory;
	}

	
	@Override
	public void afterPropertiesSet() {

		Assert.state(entityManager != null, "EntityManager must not be null!");

		super.afterPropertiesSet();
	}

	public void setEscapeCharacter(char escapeCharacter) {

		this.escapeCharacter = EscapeCharacter.of(escapeCharacter);
	}
}
public class JpaRepositoryFactory extends RepositoryFactorySupport {

	private final EntityManager entityManager;
	private final QueryExtractor extractor;
	private final CrudMethodmetadataPostProcessor crudMethodmetadataPostProcessor;

	private EntityPathResolver entityPathResolver;
	private EscapeCharacter escapeCharacter = EscapeCharacter.DEFAULT;
	private JpaQueryMethodFactory queryMethodFactory;

	
	public JpaRepositoryFactory(EntityManager entityManager) { 

		Assert.notNull(entityManager, "EntityManager must not be null!");

		this.entityManager = entityManager;
		this.extractor = PersistenceProvider.fromEntityManager(entityManager);
		this.crudMethodmetadataPostProcessor = new CrudMethodmetadataPostProcessor();
		this.entityPathResolver = SimpleEntityPathResolver.INSTANCE;
		this.queryMethodFactory = new DefaultJpaQueryMethodFactory(extractor);

		addRepositoryProxyPostProcessor(crudMethodmetadataPostProcessor);
		addRepositoryProxyPostProcessor((factory, repositoryInformation) -> {

			if (hasMethodReturningStream(repositoryInformation.getRepositoryInterface())) {
				factory.addAdvice(SurroundingTransactionDetectorMethodInterceptor.INSTANCE);
			}
		});

		if (extractor.equals(PersistenceProvider.ECLIPSElink)) {
			addQueryCreationListener(new EclipselinkProjectionQueryCreationListener(entityManager));
		}
	}

	
	@Override
	protected final JpaRepositoryImplementation getTargetRepository(RepositoryInformation information) {

		JpaRepositoryImplementation repository = getTargetRepository(information, entityManager);
		repository.setRepositoryMethodmetadata(crudMethodmetadataPostProcessor.getCrudMethodmetadata());
		repository.setEscapeCharacter(escapeCharacter);

		return repository;
	}

	//返回一个实现JpaRepositoryImplementation接口的实例,肯定是SimpleJpaRepository
	protected JpaRepositoryImplementation getTargetRepository(RepositoryInformation information,
			EntityManager entityManager) {

		JpaEntityInformation entityInformation = getEntityInformation(information.getDomainType());
		Object repository = getTargetRepositoryViaReflection(information, entityInformation, entityManager);

		Assert.isInstanceOf(JpaRepositoryImplementation.class, repository);

		return (JpaRepositoryImplementation) repository;
	}

	//直接返回了一个SimpleJpaRepository类
	@Override
	protected Class getRepositorybaseClass(Repositorymetadata metadata) {
		return SimpleJpaRepository.class;
	}


	
	@Override
	@SuppressWarnings("unchecked")
	public  JpaEntityInformation getEntityInformation(Class domainClass) {

		return (JpaEntityInformation) JpaEntityInformationSupport.getEntityInformation(domainClass, entityManager);
	}
    
    //------------------------省略了一些看不懂的----------------------

	
}

最后看一下类图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uyxt5bBF-1633519359935)(F:LocalTyproPictruedatajpa.png)]

y = getTargetRepository(information, entityManager);
repository.setRepositoryMethodmetadata(crudMethodmetadataPostProcessor.getCrudMethodmetadata());
repository.setEscapeCharacter(escapeCharacter);

	return repository;
}

//返回一个实现JpaRepositoryImplementation接口的实例,肯定是SimpleJpaRepository
protected JpaRepositoryImplementation getTargetRepository(RepositoryInformation information,
		EntityManager entityManager) {

	JpaEntityInformation entityInformation = getEntityInformation(information.getDomainType());
	Object repository = getTargetRepositoryViaReflection(information, entityInformation, entityManager);

	Assert.isInstanceOf(JpaRepositoryImplementation.class, repository);

	return (JpaRepositoryImplementation) repository;
}

//直接返回了一个SimpleJpaRepository类
@Override
protected Class getRepositorybaseClass(Repositorymetadata metadata) {
	return SimpleJpaRepository.class;
}



@Override
@SuppressWarnings("unchecked")
public  JpaEntityInformation getEntityInformation(Class domainClass) {

	return (JpaEntityInformation) JpaEntityInformationSupport.getEntityInformation(domainClass, entityManager);
}

//------------------------省略了一些看不懂的----------------------

}
最后看一下类图

感想:源码里大量的使用了流操作和Optional操作,很有学习价值

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号