[내일배움캠프 Spring 4기] 70일차 TIL - Auditing

서예진·2024년 3월 13일
0

오늘의 학습 키워드

Auditing


Auditing

엔티티의 이벤트를 감시하는 Auditing

  • Auditing 을 사용하면 엔티티를 누가 언제 생성/마지막 수정 했는지 자동으로 기록되게 할 수 있다.
@CreatedDate
private Date created;

@LastModifiedDate
private Date updated;

@CreatedBy
@ManyToOne
private Account createdBy;

@LastModifiedBy
@ManyToOne
private Account updatedBy;

Auditing 적용

  1. 메인 애플리케이션 위에 @EnableJpaAuditing 추가

    @EnableJpaAuditing
    @SpringBootApplication
    public class Application {
  2. 엔티티 클래스 위에 @EntityListeners(AuditingEntityListener.class) 추가

    @Getter
    @MappedSuperclass
    @EntityListeners(AuditingEntityListener.class)
    public class TimeStamp {
        @CreatedDate
        private LocalDateTime createdAt;
    
        @CreatedBy
        @ManyToOne
        private User createdBy;
    
        @LastModifiedDate
        private LocalDateTime modifiedAt;
    
        @LastModifiedBy
        @ManyToOne
        private User modifiedBy;
    }
    • MappedSuperclass : MappedSuperclass를 상속받으면 persistence가 같이 유지됨
  3. AuditorAware 구현체 만들기

    1. createdAt, modifiedAt 은 구현체 없이 동작하지만 createdBy, modifiedBy 는 구현체가 필요하다.
    2. SpringSecurity 의 SecurityContextHolder 에서 인증정보안에 담긴 UserDetailsImpl 을 사용하여 user 객체를 가져와서 넣어준다.
      • SpringSecurity의 JwtFilter 에서 우리가 저장해주는 부분 코드보기
        // JwtAuthFilter.java
        
        @Slf4j
        @RequiredArgsConstructor
        public class JwtAuthFilter extends OncePerRequestFilter {
        
            private final JwtUtil jwtUtil;
        
            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
                String token = jwtUtil.resolveToken(request);
        
                if(token != null) {
                    if(!jwtUtil.validateToken(token)){
                        jwtExceptionHandler(response, "Token Error", HttpStatus.UNAUTHORIZED.value());
                        return;
                    }
                    Claims info = jwtUtil.getUserInfoFromToken(token);
        						// 인증정보 세팅함수 호출
                    setAuthentication(info.getSubject());
                }
                try {
                    filterChain.doFilter(request, response);
                }catch(FileUploadException e){
                    jwtExceptionHandler(response,"File Upload Error",400);
                }
            }
        
            public void setAuthentication(String username) {
        				// SecurityContextHolder 는 threadLocal 로 구현되어 요청쓰레드내에서 공유할 수 있다.
                SecurityContext context = SecurityContextHolder.createEmptyContext();
                Authentication authentication = jwtUtil.createAuthentication(username);
        				// 요기서 인증정보(계정정보)를 담아준다.
                context.setAuthentication(authentication);
        
                SecurityContextHolder.setContext(context);
            }
        		...
        }
    @Service
    public class UserAuditorAware implements AuditorAware<User> {
        @Override
        public Optional<User> getCurrentAuditor() { //AuditorAware의 getCurrentAuditor() 메서드를 구현
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); //인증정보를 받아옴
    			
            if (authentication == null || !authentication.isAuthenticated()) {
                return Optional.empty();
            }
    
            return Optional.of(((UserDetailsImpl) authentication.getPrincipal()).getUser());
        }
    }
  4. @EnableJpaAuditing에 AuditorAware 빈 이름 설정하기.

Auditing 구현

  • 생성일시, 생성자, 수정일시, 수정자는 결국 엔티티의 영속성이 변경될때 저장한다.
  • 엔티티의 영속성이 변경되는 생성 > 수정 > 삭제 이 흐름을 엔티티 라이프 사이클 이벤트라고 한다.
  • Auditing 도 이러한 엔티티의 라이프 사이클 이벤트를 통해 구현하고있다.
  • 우린 엔티티 라이프 사이클을 직접 관리하여 구현할 수 있다.

엔티티 저장 이벤트

전 : @PrePersist : EntityManager 가 엔티티를 영속성상태로 만들기 직전에 메소드 수행

후 : @PostPersist : EntityManager 가 엔티티를 영속성상태로 만든 직후에 메소드 수행

엔티티 수정 이벤트

전 : @PreUpdate : EntityManager 가 엔티티를 갱신상태로 만들기 직전에 메소드 수행

후 : @PostUpdate : EntityManager 가 엔티티를 갱신상태로 만든 직후에 메소드 수행

엔티티 삭제 이벤트

전 : @PerRemove : EntityManager 가 엔티티를 삭제상태로 만들기 직전에 메소드 수행

후 : @PostRemove : : EntityManager 가 엔티티를 삭제상태로 만든 직후에 메소드 수행

createdAt, modifiedAt 구현

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class TimeStamp {

	@CreatedDate
	private LocalDateTime createdAt;

	@CreatedDate
	private LocalDateTime modifiedAt;

}
profile
안녕하세요

0개의 댓글