????????解釋“dao”這個(gè)bean。這里衍生一下,進(jìn)行一下名詞解釋,我們知道dao這個(gè)層叫做Data Access Object,數(shù)據(jù)庫訪問對象,這是一個(gè)廣泛的詞語,在jpa當(dāng)中,我們還有一個(gè)詞語叫做Repository,這里我們一般就用Repository結(jié)尾來表示這個(gè)dao,比如UserDao,這里我們使用UserRepository,當(dāng)然名字無所謂,隨意取,你可以意會一下我的意思,感受一下這里的含義和區(qū)別,同理,在mybatis中我們一般也不叫dao,mybatis由于使用xml映射文件(當(dāng)然也提供注解,但是官方文檔上面表示在有些地方,比如多表的復(fù)雜查詢方面,注解還是無解,只能xml),我們一般使用mapper結(jié)尾,比如我們也不叫UserDao,而叫UserMapper。
? ? ? ? 然而,我們的UserRepository和UserRepositoryImpl這兩個(gè)類就像下面這樣來寫。
????????public interface UserRepository extends JpaRepository{}
????????public class UserRepositoryImpl {}
????那么這里為什么要這么做呢?原因是:spring-data-jpa提供基礎(chǔ)的CRUD工作,同時(shí)也提供業(yè)務(wù)邏輯的功能(前面說了,這是該框架的威力所在),所以我們的Repository接口要做兩項(xiàng)工作,繼承spring-data-jpa提供的基礎(chǔ)CRUD功能的接口,比如JpaRepository接口,同時(shí)自己還需要在UserRepository這個(gè)接口中定義自己的方法,那么導(dǎo)致的結(jié)局就是UserRepository這個(gè)接口中有很多的方法,那么如果我們的UserRepositoryImpl實(shí)現(xiàn)了UserRepository接口,導(dǎo)致的后果就是我們勢必需要重寫里面的所有方法,這是Java語法的規(guī)定,如此一來,悲劇就產(chǎn)生了,UserRepositoryImpl里面我們有很多的@Override方法,這顯然是不行的,結(jié)論就是,這里我們不用去寫implements部分。
????????spring-data-jpa實(shí)現(xiàn)了上面的能力,那他是怎么實(shí)現(xiàn)的呢?這里我們通過源代碼的方式來呈現(xiàn)他的來龍去脈,這個(gè)過程中cglib發(fā)揮了杰出的作用。
? ? ? ? 在spring-data-jpa內(nèi)部,有一個(gè)類,叫做:
????????public class SimpleJpaRepository implements JpaRepository, JpaSpecificationExecutor
????????我們可以看到這個(gè)類是實(shí)現(xiàn)了JpaRepository接口的,事實(shí)上如果我們按照上面的配置,在同一個(gè)包下面有UserRepository,但是沒有UserRepositoryImpl這個(gè)類的話,在運(yùn)行時(shí)期UserRepository這個(gè)接口的實(shí)現(xiàn)就是上面的SimpleJpaRepository這個(gè)接口。而如果有UserRepositoryImpl這個(gè)文件的話,那么UserRepository的實(shí)現(xiàn)類就是UserRepositoryImpl,而UserRepositoryImpl這個(gè)類又是SimpleJpaRepository的子類,如此一來就很好的解決了上面的這個(gè)不用寫implements的問題。我們通過閱讀這個(gè)類的源代碼可以發(fā)現(xiàn),里面包裝了entityManager,底層的調(diào)用關(guān)系還是entityManager在進(jìn)行CRUD。
????????spring-data-jpa為什么把Repository和RepositoryImpl文件放在同一個(gè)包下面,因?yàn)槲覀兊膽?yīng)用很可能根本就一個(gè)Impl文件都不存在,那么在那個(gè)包下面就只有一堆接口,即使把Repository和RepositoryImpl都放在同一個(gè)包下面,也不會造成這個(gè)包下面有正常情況下2倍那么多的文件,根本原因:只有接口而沒有實(shí)現(xiàn)類。
????????UserRepository類繼承了JpaRepository和JpaSpecificationExecutor類,而我們的UserReposit-ory這個(gè)對象都會注入到UserService里面,于是如果使用這種方式,我們的邏輯直接就寫在service里面了