878
技術社區[雲棲]
《Spring Data 官方文檔》4.6 定製Spring Data倉庫實現
4.6 定製Spring Data倉庫實現
經常有必要為一少部分倉庫方法,提供一個定製的實現。Spring數據存儲庫允許您提供自定義存儲庫代碼。並將其與通用CRUD集成抽象和查詢方法功能整合.
4.6.1 為單獨倉庫添加定製行為
為了定製功能豐富一個倉庫,你首先為定製功能定義一個接口和實現.使用你提供的倉庫接口來繼承自定義接口.
例20. 定製倉庫功能的接口
interface UserRepositoryCustom { public void someCustomMethod(User user); }
例21.定製功能的實現
class UserRepositoryImpl implements UserRepositoryCustom { public void someCustomMethod(User user) { // Your custom implementation } }
注意
類可以被找到最重要的一點是名字以Impl為後綴區別於倉庫的核心接口(見下文)
實現的本身沒有依賴Spring Data,可以是一個標準的Spring bean.所以你可以使用標準的依賴注入行為給其他bean注入引用,像JdbcTemplate,切麵的一部分等等.
例22 修改你基本的倉庫接口
interface UserRepository extends CrudRepository<User, Long>, UserRepositoryCustom { // Declare query methods here }
讓你的標準倉庫接口繼承定製的.這樣做結合了CRUD和定製功能並使其可用於客戶端.
配置
如果你使用命名空間配置,倉庫基本組件掃描類所在的包,根據掃描結果嚐試自動定製實現.這些類需要遵循命名規範:給倉庫接口名添加命名空間元素屬性repositoryimpl-postfix.默認的後綴是Impl.
例23. 配置示例
<repositories base-package="com.acme.repository" /> <repositories base-package="com.acme.repository" repository-impl-postfix="FooBar"/>
第一個配置示例將查實查找一個類com.acme.repository.UserRepositoryImpl來作為定製倉庫實現.而第二個示例將嚐試查找com.acme.repository.UserRepositoryFooBar.
手動指定
上麵的方法可以正常工作,隻有當你的定製實現使用注解配置和自動注入,它將與其他Spring bean一樣被對待.如果你定製的實現需要特殊處理,你可以像描述那樣簡單定義一個bean並且命名它.基本組件將通過名稱引用手動定義的bean定義而不是它自己創建一個.
例24.手動指定定製實現
<repositories base-package="com.acme.repository" /> <beans:bean > <!-- further configuration --> </beans:bean>
4.6.2 為所有倉庫添加定製行為
當你希望把一個單獨的方法添加到你所有的倉庫接口中時,上麵的方法就不可行了.為了添加定製到所有的倉庫,你首先添加一個中間接口來定義共享的行為.
例25 定義共享定製行為接口
@NoRepositoryBean public interface MyRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> { void sharedCustomMethod(ID id); }
現在你的每個倉庫接口將繼承這個中間接口而不是Repository接口來包含功能的定義.接下來創建一個中間接口的實現繼承持久化具體倉庫的基本類.這個類後麵將作為倉庫代理的基本類.
例26 定製倉庫基本類
public class MyRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>implements MyRepository<T, ID> { private final EntityManager entityManager; public MyRepositoryImpl(JpaEntityInformation entityInformation,EntityManager entityManager) { super(entityInformation, entityManager); // Keep the EntityManager around to used from the newly introduced methods. this.entityManager = entityManager; } public void sharedCustomMethod(ID id) { // implementation goes here } }
警告
這個類需要有一個構造方法調用父類具體存儲倉庫工廠實現.萬一倉庫基礎類有多個構造,覆蓋包括一個EntityInformation加上存儲具體基本組件對象(例如一個EntityManager或者模板類)
Spring命名空間下的默認行為為所有接口提供一個實現.這意味著如果在當前狀態下,Spring將創建一個MyRepository的實例.這當然不是被期望的,它隻是作為一個用來定義實體的 Repository和真實倉庫接口的中間接口.為了排除一個繼承Repository的接口被當做一個倉庫接口被實例化,你可以給它使用@NoRepositoryBean(像上麵)或者把它從配置中base-package移除.
最後一步是讓Spring Data基本組件識別到定製的倉庫基本類.在JavaConf使用注解@Enable…Repository的屬性repositoryBaseClass完成:
例27 使用JavaConfig配置一個定製倉庫基本類
@Configuration @EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class) class ApplicationConfiguration { … }
類似的屬性在XML命名空間中也可以找到.
例28 使用XML配置一個定製倉庫基本類
<repositories base-package="com.acme.repository" base- />
最後更新:2017-05-19 11:31:48