之前为了让代码跑起来,我们已经通过Java代码对Spring Data进行了配置。再此,我们将进一步学习,包括XML方式。
XML配置涉及两个namespace:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入namespace,另外schemaLocation中请注意project采用的版本 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:data="http://www.springframework.org/schema/data/repository"
xmlns:data-jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/data/repository
http://www.springframework.org/schema/data/repository/spring-repository-1.6.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd">
<!-- populator: 根据文件(json或者XML)来填充仓库的数据,其作用相当于最后在表格中预设某些条目。这是危险的,不会在生产环境中使用。例子中data:jackson2-populator定义一个bean(bean名字可在可选的id属性中指定),使用Jackson Data Processor 2.x ObjectMapper作为文件解析器,解析器的bean名字在object-mapper-ref中定义。此外还有data:jackson-populator,这是使用Jackson Data Processor 1.x ObjectMapper,还有xml的data:unmarshaller-populator,使用unmarshaller-ref来说明解析器的bean名。这是一个json文件的例子:-->
<!-- [{"_class" : "com.some.Class", -->
<!-- "id" : "id1", -->
<!-- "firstname" : "Admin", -->
<!-- "lastname" : "admin" -->
<!-- }, -->
<!-- {"_class" : "com.some.Class", -->
<!-- "id" : "id2", -->
<!-- "firstname" : "user", -->
<!-- "lastname" : "user" -->
<!-- }] -->
<data:jackson2-populator locations="classpath:com/sample/config/inserts.json"
object-mapper-ref="objectMapper" />
<!-- 这是重点,也是之前我们在java代码中配置的@EnableJpaRepositories所对应,属性有: -->
<!-- ➤ base-package 必须:将扫描扩展了org.springframework.data.repository.Repository接口,没有标记@NoRepositoryBean,为它们生成接口的实现。-->
<!-- ➤ named-queries-location 可选:这个不是Spring Data的,而是JPA的,就是我们使用entityManager.createNamedQuery()中的预定义JPQL,相当于相当于Entity代码中的@NamedQueries,我们可以定义.properties文件包含这些预定义。 -->
<!-- ➤ repository-impl-postfix 可选:缺省是Impl,也就是BookRepository的自定义方法实现会自动查找BookRepositoryImpl。 -->
<!-- ➤ query-lookup-strategy 可选:查找的策略,缺省是create-if-not-found,表示使用已定义的查询方法,如果不匹配,则根据规则(例如find...By...)创建该方法的实现。use-declared-query表示只使用已定义的,不根据方法名创建查询的实现;create则表示不使用已定义的,只使用根据方法名创建查询的实现。-->
<!-- ➤ factory-class 可选,定义非缺省的repository factory bean -->
<!-- ➤ transaction-manager-ref 可选,如果不指定,则采用Spring framework缺省的PlatformTransactionManager -->
<!-- Spring data JPA特有的属性: -->
<!-- ➤ entity-manager-factory-ref 可选,缺省为的Bean为entityManagerFactory,如果不是,需要明确指出 -->
<data-jpa:repositories base-package="com.sample"
transaction-manager-ref="jpaTransactionManager"
entity-manager-factory-ref="entityManagerFactoryBean"
query-lookup-strategy="create">
<!-- 在data-jpa:repositories中的子element有: -->
<!-- ➤ <data:include-filter>接口自动生成代码必须要符合的条件,类似于<context:component-scan>中的<context:include-filter> -->
<!-- ➤ <data:exclude-filter>接口自动生成代码必须不满足的条件,类似于<context:component-scan>中的<context:exclude-filter> -->
<!-- 例如我们将JPA DB和MongoDB的repository接口都放在同一个package中(当然分开放也可轻松解决问题),那么扫描到扩展Repository接口的就好自动生成代码,这样会生成两份代码,造成错误。我们通过include-filter做进一步限制,只有扩展JpaRepository的生产Spring data JPA相关的代码,而扩展MongoRepository生成Spring data mongo的代码,例如如下:-->
<!-- <data-jpa:repositories base-package="com.sample"> -->
<!-- <data:include-filter type="assignable" expression="org.springframework.data.jpa.repository.JpaRepository" /> -->
<!-- </data-jpa:repositories> -->
<!-- <data-mongo:repositories base-package="com.sample"> -->
<!-- <data:include-filter type="assignable" expression="org.springframework.data.mongodb.repository.MongoRepository" /> -->
<!-- </data-mongo:repositories> -->
<data:include-filter type="annotation" expression="com.sample.MyRepository" />
</data-jpa:repositories>
<!-- 当允许审计Spring Data在保存entity时,可以设置特定的entity属性,例如谁保存,什么时间保存。其他的spring data项目有也有类似的元素。含有以下属性:-->
<!-- ➤ auditor-aware-ref 是an org.springframework.data.domain.AuditorAware<U>的实现的Bean名字,检查当前的认证用户或principal。如果无此属性,审计将不会记录那个用户进行了修改。 -->
<!-- ➤ set-dates 缺省值为true,表明当创建或者修改时,记录是否要设置日期。 -->
<!-- ➤ date-time-provider-ref org..springframework.data.auditing.DateTimeProvider实现的bean名字,缺省为org.springframework.data.auditing.CurrentDateTimeProvider,基于Calendar。-->
<!-- ➤ modify-on-creation 缺省值为true,表明是否在创建时设置修改日期,如果为false,则修改日期只在update的时候设置,create不设置。-->
<data-jpa:auditing auditor-aware-ref="auditorAwareImpl" />
</beans>
一般来讲我们只设置data-jpa:repositories。
通过@EnableJpaRepositories来替代 <data-jpa:repositories>的相关配置,这也是我们之前小例子的做法。
@EnableJpaRepositories标记:
@ComponentScan.Filter标记
例子如下:
@Configuration
...
@EnableJpaRepositories( basePackages = "com.wrox.site.repositories",
entityManagerFactoryRef = "entityManagerFactoryBean",
transactionManagerRef = "jpaTransactionManager"
)
...
public class RootContextConfiguration implements AsyncConfigurer, SchedulingConfigurer{
...
}
如果set-dates=true,modify-on-creation=true(缺省值),我们只需定义AuditorAware 的Bean即可。
如果上述两个中有false,我们只能使用XML的,在Java代码中,通过@ImportResource来提供XML的配置。
更常见的情况,审计是基于entity,我们可以在entity的属性上标记,表明这是一个审计的列。注意,属性不能同时具有下面两个或以上的标记。
Spring data可以和Spring MVC的接口参数进行自动转换,例如Pageable和Sort。
@RequestMapping("/person/{id}")
/* Spring data可以自动调用findOne(),根据id来获取具体的Person对象。*/
public String viewPerson(@PathVariable("id") Person person){
......
}
只需在DispatcherServlet的配置类上加上@org.springframework.data.web.config.EnableSpringDataWebSupport即可,可以自动注册下面的bean
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
@ComponentScan( basePackages = "com.wrox.site",
useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(WebController.class) )
public class WebServletContextConfiguration extends WebMvcConfigurerAdapter
EnableSpringDataWebSupport使用缺省值,包括名字,最大的page数,缺省的Pageable和Sort的值等等。如果你不适用缺省值,需要自己定义,那么删除@EnableSpringDataWebSupport,手动注册这些bean。相关的代码例子在后面学习。