查看: 620|回复: 0

[Java学习] 基于Spring Data的AuditorAware审计功能的示例代码

发表于 2018-4-15 08:00:01

Spring Data提供支持审计功能:即由谁在什么时候创建或修改实体。Spring Data提供了在实体类的属性上增加@CreatedBy,@LastModifiedBy,@CreatedDate,@LastModifiedDate注解,并配置相应的配置项,即可实现审计功能,有系统自动记录 createdBy CreatedDate lastModifiedBy lastModifiedDate 四个属性的值,下面为具体的配置项。

示例

创建一个实体类

  1. package com.hfcsbc.infrastructureservice.domain;
  2. import com.hfcsbc.repository.support.domain.AbstractAuditingEntity;
  3. import lombok.Data;
  4. import org.springframework.data.annotation.CreatedBy;
  5. import org.springframework.data.annotation.CreatedDate;
  6. import org.springframework.data.annotation.LastModifiedBy;
  7. import org.springframework.data.annotation.LastModifiedDate;
  8. import org.springframework.data.jpa.domain.support.AuditingEntityListener;
  9. import javax.persistence.*;
  10. import java.util.Date;
  11. /**
  12. * Create by pengchao on 2018/3/7
  13. */
  14. @Entity
  15. @Data
  16. @EntityListeners({AuditingEntityListener.class})
  17. public class Person {
  18. @Id
  19. @GeneratedValue
  20. private Long id;
  21. private String name;
  22. private Integer age;
  23. @CreatedBy
  24. @Column(
  25. name = "created_by",
  26. nullable = false,
  27. length = 50,
  28. updatable = false
  29. )
  30. private String createdBy;
  31. @CreatedDate
  32. @Column(
  33. name = "created_date",
  34. nullable = false,
  35. updatable = false
  36. )
  37. private Date createdDate = new Date();
  38. @LastModifiedBy
  39. @Column(
  40. name = "last_modified_by",
  41. length = 50
  42. )
  43. private String lastModifiedBy;
  44. @LastModifiedDate
  45. @Column(
  46. name = "last_modified_date"
  47. )
  48. private Date lastModifiedDate = new Date();
  49. }
复制代码

创建相应的Repository

  1. package com.hfcsbc.repository;
  2. import com.hfcsbc.domain.Person;
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. /**
  5. * Create by pengchao on 2018/3/7
  6. */
  7. public interface PersonRepository extends JpaRepository<Person, Long> {
  8. }
复制代码

配置获取用户信息的bean

  1. package com.hfcsbc.infrastructureservice.config;
  2. import org.springframework.data.domain.AuditorAware;
  3. import org.springframework.security.core.Authentication;
  4. import org.springframework.security.core.context.SecurityContextHolder;
  5. import org.springframework.stereotype.Component;
  6. import java.util.Optional;
  7. /**
  8. * Create by pengchao on 2018/3/7
  9. */
  10. @Component("auditorAware")
  11. public class AuditorAwareImpl implements AuditorAware<String> {
  12. @Override
  13. public Optional<String> getCurrentAuditor() {
  14. Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
  15. return Optional.of(authentication.getPrincipal().toString());
  16. }
  17. }
复制代码

在Spring Boot入口类开启审计功能

  1. package com.hfcsbc.infrastructureservice;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
  5. import org.springframework.scheduling.annotation.EnableAsync;
  6. @SpringBootApplication
  7. @EnableJpaAuditing(auditorAwareRef = "auditorAware")
  8. @EnableAsync
  9. public class PersonApplication {
  10. public static void main(String[] args) {
  11. SpringApplication.run(PersonApplication.class, args);
  12. }
  13. }
复制代码

即完成配置,在使用 repository 保存对象时, createdBy CreatedDate lastModifiedBy lastModifiedDate 有审计功能自动插入

注:在异步方法中如何获取用户信息

由于在异步方法中使用repository保存对象,获取不到用户用户信息,需增加如下配置项,即可在Authentication获取用户的信息

  1. package com.hfcsbc.config;
  2. import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.security.core.context.SecurityContextHolder;
  6. /**
  7. * Create by pengchao on 2018/3/7
  8. */
  9. @Configuration
  10. public class AuditorAwareConfig {
  11. @Bean
  12. public MethodInvokingFactoryBean methodInvokingFactoryBean() {
  13. MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
  14. methodInvokingFactoryBean.setTargetClass(SecurityContextHolder.class);
  15. methodInvokingFactoryBean.setTargetMethod("setStrategyName");
  16. methodInvokingFactoryBean.setArguments(new String[]{SecurityContextHolder.MODE_INHERITABLETHREADLOCAL});
  17. return methodInvokingFactoryBean;
  18. }
  19. }
复制代码

SecurityContextHolder的主要功能是将当前执行的进程和SecurityContext关联起来。

SecurityContextHolder.MODE_INHERITABLETHREADLOCAL :用于线程有父子关系的情景中,子线程集成父线程的SecurityContextHolder;

SecurityContextHolder.MODE_INHERITABLETHREADLOCAL :全局共用SecurityContextHolder。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。



回复

使用道具 举报