继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Spring认证中国教育管理中心-Spring Data JPA 参考文档七

Adobe国际认证
关注TA
已关注
手记 131
粉丝 9
获赞 28

原标题:Spring认证|Spring Data JPA 参考文档七(内容来源:Spring中国教育管理中心)

5.1.8. 锁定

要指定要使用的锁定模式,您可以@Lock在查询方法上使用注释,如以下示例所示:

示例 110.在查询方法上定义锁元数据

interface UserRepository extends Repository<User, Long> {

// Plain query method

@Lock(LockModeType.READ)

List<User> findByLastname(String lastname);

}

此方法声明导致被触发的查询配备一个LockModeTypeof READ。您还可以通过在存储库接口中重新声明 CRUD 方法并添加@Lock注释来为 CRUD 方法定义锁定,如以下示例所示:

示例 111.在 CRUD 方法上定义锁元数据

interface UserRepository extends Repository<User, Long> {

// Redeclaration of a CRUD method

@Lock(LockModeType.READ)

List<User> findAll();

}

5.1.9. 审计

基本

Spring Data 提供了复杂的支持,以透明地跟踪谁创建或更改了实体以及更改发生的时间。要从该功能中受益,您必须为实体类配备审计元数据,这些元数据可以使用注释或通过实现接口来定义。此外,必须通过 Annotation 配置或 XML 配置启用审计以注册所需的基础架构组件。有关配置示例,请参阅特定于商店的部分。

仅跟踪创建和修改日期的应用程序不需要指定AuditorAware.

基于注释的审计元数据

我们提供@CreatedBy并@LastModifiedBy捕获创建或修改实体的用户,@CreatedDate并@LastModifiedDate捕获更改发生的时间。

示例 112. 一个被审计的实体

class Customer {

@CreatedBy

private User user;

@CreatedDate

private Instant createdDate;

// … further properties omitted

}

如您所见,可以有选择地应用注释,具体取决于您要捕获的信息。进行更改时捕获的注释可用于 Joda-Time DateTime、旧版 JavaDate和Calendar、JDK8 日期和时间类型以及long或Long.

审计元数据不一定需要存在于根级实体中,但可以添加到嵌入式实体中(取决于实际使用的存储),如下面的截图所示。

示例 113. 审计嵌入实体中的元数据

class Customer {

private AuditMetadata auditingMetadata;

// … further properties omitted

}

class AuditMetadata {

@CreatedBy

private User user;

@CreatedDate

private Instant createdDate;

}

http://img.mukewang.com/61823dda0001615011960435.jpg


基于接口的审计元数据

如果您不想使用注释来定义审计元数据,您可以让您的域类实现该Auditable接口。它公开了所有审计属性的 setter 方法。

AuditorAware

如果您使用@CreatedBy或@LastModifiedBy,审计基础结构需要以某种方式了解当前主体。为此,我们提供了一个AuditorAware<T>SPI 接口,您必须实现该接口以告知基础设施当前与应用程序交互的用户或系统是谁。泛型类型T定义了用什么类型注释的属性@CreatedBy或@LastModifiedBy必须是什么类型。

以下示例显示了使用 Spring SecurityAuthentication对象的接口的实现:

Example 114.AuditorAware基于 Spring Security 的实现

class SpringSecurityAuditorAware implements AuditorAware<User> {

@Override

public Optional<User> getCurrentAuditor() {

return Optional.ofNullable(SecurityContextHolder.getContext())

.map(SecurityContext::getAuthentication)

.filter(Authentication::isAuthenticated)

.map(Authentication::getPrincipal)

.map(User.class::cast);

}

}

该实现访问AuthenticationSpring Security 提供的对象并查找UserDetails您在UserDetailsService实现中创建的自定义实例。我们在这里假设您通过UserDetails实现公开域用户,但根据Authentication发现,您也可以从任何地方查找它。

ReactiveAuditorAware

使用反应式基础架构时,您可能希望使用上下文信息来提供@CreatedBy或提供@LastModifiedBy信息。我们提供了一个ReactiveAuditorAware<T>SPI 接口,您必须实现该接口才能告诉基础设施当前与应用程序交互的用户或系统是谁。泛型类型T定义了用什么类型注释的属性@CreatedBy或@LastModifiedBy必须是什么类型。

以下示例显示了使用响应式 Spring SecurityAuthentication对象的接口的实现:

Example 115.ReactiveAuditorAware基于 Spring Security 的实现

class SpringSecurityAuditorAware implements ReactiveAuditorAware<User> {

@Override

public Mono<User> getCurrentAuditor() {

return ReactiveSecurityContextHolder.getContext()

.map(SecurityContext::getAuthentication)

.filter(Authentication::isAuthenticated)

.map(Authentication::getPrincipal)

.map(User.class::cast);

}

}

该实现访问AuthenticationSpring Security 提供的对象并查找UserDetails您在UserDetailsService实现中创建的自定义实例。我们在这里假设您通过UserDetails实现公开域用户,但根据Authentication发现,您也可以从任何地方查找它。

还有一个方便的基类 ,AbstractAuditable您可以对其进行扩展以避免需要手动实现接口方法。这样做会增加域类与 Spring Data 的耦合,这可能是您想要避免的。通常,定义审计元数据的基于注释的方法是首选,因为它侵入性更小且更灵活。

5.1.10. JPA审计

常规审计配置

Spring Data JPA 附带一个实体侦听器,可用于触发审计信息的捕获。首先,您必须AuditingEntityListener在orm.xml文件内的持久性上下文中注册要用于所有实体的,如以下示例所示:

示例 116.审计配置 orm.xml

<persistence-unit-metadata>

<persistence-unit-defaults>

<entity-listeners>

<entity-listener class="….data.jpa.domain.support.AuditingEntityListener" />

</entity-listeners>

</persistence-unit-defaults>

</persistence-unit-metadata>

您还可以AuditingEntityListener使用@EntityListeners注释在每个实体的基础上启用,如下所示:

@Entity

@EntityListeners(AuditingEntityListener.class)

public class MyEntity {

}

审计功能需要spring-aspects.jar在类路径上。

随着orm.xml适当地修改和spring-aspects.jar类路径上的,激活审核功能是将所述弹簧数据JPA事项auditing名字空间元素到您的配置,如下所示:

示例 117. 使用 XML 配置激活审计

<jpa:auditing auditor-aware-ref="yourAuditorAwareBean" />

从 Spring Data JPA 1.5 开始,您可以通过使用注释对配置类进行@EnableJpaAuditing注释来启用审计。您仍然必须修改orm.xml文件并spring-aspects.jar在类路径上有。以下示例显示了如何使用@EnableJpaAuditing注释:

示例 118. 使用 Java 配置激活审计

@Configuration

@EnableJpaAuditing

class Config {

@Bean

public AuditorAware<AuditableUser> auditorProvider() {

return new AuditorAwareImpl();

}

}

如果您向 公开类型AuditorAware为 的bean ApplicationContext,审计基础结构会自动选取它并使用它来确定要在域类型上设置的当前用户。如果您在 中注册了多个实现,则ApplicationContext可以通过显式设置 的auditorAwareRef属性来选择要使用的一个@EnableJpaAuditing。

5.2. 其他注意事项

5.2.1. 使用JpaContext在自定义实现

当使用多个EntityManager实例和自定义存储库实现时,您需要将正确的连接EntityManager到存储库实现类中。您可以通过EntityManager在@PersistenceContext注释中显式命名 来实现,或者,如果EntityManager是@Autowired,则使用@Qualifier。

从 Spring Data JPA 1.9 开始,Spring Data JPA 包含一个名为的类,假设它仅由应用程序中的一个实例管理,JpaContext您可以EntityManager通过该类获取受管理的域类EntityManager。以下示例显示了如何JpaContext在自定义存储库中使用:

示例 119.JpaContext在自定义存储库实现中使用

class UserRepositoryImpl implements UserRepositoryCustom {

private final EntityManager em;

@Autowired

public UserRepositoryImpl(JpaContext context) {

this.em = context.getEntityManagerByManagedType(User.class);

}

}

这种方法的优点是,如果域类型被分配给不同的持久性单元,则不必接触存储库来更改对持久性单元的引用。

5.2.2. 合并持久化单元

Spring 支持拥有多个持久化单元。然而,有时您可能希望对应用程序进行模块化,但仍要确保所有这些模块都在单个持久性单元中运行。为了实现这种行为,Spring Data JPA 提供了一个PersistenceUnitManager实现,它根据名称自动合并持久性单元,如以下示例所示:

示例 120.使用
MergingPersistenceUnitmanager

<bean class="….LocalContainerEntityManagerFactoryBean">

<property name="persistenceUnitManager">

<bean class="….MergingPersistenceUnitManager" />

</property>

</bean>

@Entity 类和 JPA 映射文件的类路径扫描

一个普通的 JPA 设置需要在orm.xml. 这同样适用于 XML 映射文件。Spring Data JPA 提供了一个
ClasspathScanningPersistenceUnitPostProcessor获取基本包配置并可选地采用映射文件名模式的方法。然后它扫描给定包中用@Entityor注释的类@MappedSuperclass,加载与文件名模式匹配的配置文件,并将它们交给 JPA 配置。后处理器必须配置如下:

示例 121.使用
ClasspathScanningPersistenceUnitPostProcessor

<bean class="….LocalContainerEntityManagerFactoryBean">

<property name="persistenceUnitPostProcessors">

<list>

<bean class="org.springframework.data.jpa.support.ClasspathScanningPersistenceUnitPostProcessor">

<constructor-arg value="com.acme.domain" />

<property name="mappingFileNamePattern" value="**/*Mapping.xml" />

</bean>

</list>

</property>

</bean>

从 Spring 3.1 开始,可以
LocalContainerEntityManagerFactoryBean直接在 上配置要扫描的包,以启用实体类的类路径扫描。有关详细信息,请参阅JavaDoc。

5.2.3. CDI集成

存储库接口的实例通常由容器创建,因此在使用 Spring Data 时,Spring 是最自然的选择。Spring 为创建 bean 实例提供了复杂的支持,如创建存储库实例中所述。从 version 1.1.0 开始,Spring Data JPA 附带了一个自定义 CDI 扩展,允许在 CDI 环境中使用存储库抽象。该扩展是 JAR 的一部分。要激活它,请在您的类路径中包含 Spring Data JPA JAR。

您现在可以通过为EntityManagerFactoryand实现 CDI Producer 来设置基础结构EntityManager,如以下示例所示:

class EntityManagerFactoryProducer {

@Produces

@ApplicationScoped

public EntityManagerFactory createEntityManagerFactory() {

return Persistence.createEntityManagerFactory("my-persistence-unit");

}

public void close(@Disposes EntityManagerFactory entityManagerFactory) {

entityManagerFactory.close();

}

@Produces

@RequestScoped

public EntityManager createEntityManager(EntityManagerFactory entityManagerFactory) {

return entityManagerFactory.createEntityManager();

}

public void close(@Disposes EntityManager entityManager) {

entityManager.close();

}

}

http://img1.mukewang.com/61823ddb000106b911990516.jpg


必要的设置可能因 JavaEE 环境而异。您可能只需要将 a 重新声明EntityManager为 CDI bean,如下所示:

class CdiConfig {

@Produces

@RequestScoped

@PersistenceContext

public EntityManager entityManager;

}

在前面的示例中,容器必须能够EntityManagers自己创建 JPA 。所有配置所做的就是将 JPA 重新导出EntityManager为 CDI bean。

Spring Data JPA CDI 扩展将所有可用EntityManager实例作为 CDI bean选取,并在容器请求存储库类型的 bean 时为 Spring Data 存储库创建代理。因此,获取 Spring Data 存储库的实例是声明@Injected属性的问题,如以下示例所示:

class RepositoryClient {

@Inject

PersonRepository repository;

public void businessMethod() {

List<Person> people = repository.findAll();

}

}

内容来源:Spring中国教育管理中心(Spring认证)

http://img4.mukewang.com/61823ddc00012c3f10000562.jpg


2021年2月,VMware公司正式与北京中科卓望网络科技有限公司(以下简称:中科卓望)达成战略合作,授予其 Spring 中国教育管理中心,携手 VMware 全球最新 Spring技术和认证体系,帮助中国院校构建专业教学内容,全面赋能未来开发人。


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP