오늘은 그간 밀렸던 2,3주차 스프링 강의를 듣는데에 집중했다. 2주차는 JPA, 3주차는 필터에 관한 내용 이었는데 앞서 프로젝트를 진행하며 다른 조원이 구현했던 부분이었다. 그 때는 기능과 역할을 어렴풋이 알고 넘어 갔었는데 이번에 강의를 들으며 어느정도 이해할 수 있었다.
jpa는 Java ORM 기술의 대표적인 표준 명세이다. 이를 사용하면 DB연결 과정을 자동으로 처리해준다. 내가 사용하는 스프링부트에서는 이JPA를 실제로 구현한 프레임워크 중 가장 많이 알려진 하이버네이트 구현체를 사용한다.
이를 통해 복잡한 sql구문을 직접 작성할 필요 없이 프레임워크가 알아서 만들어 주는 것을 사용하고 로그를 통해 구상했던 대로 정상작동 하는지 확인해주면 된다.
JPA를 사용할 때 주의해야할 점이 있는데 Entity 객체들을 영속성 컨텍스트로 관리해 주어야 한다. 영속성으로 관리해야 객체가 수정 및 삭제 등의 변경 사항이 생길 때 이를 지속적으로 반영할 수 있다.
스프링에서는 이 기능을 편리하게 사용할 수 있도록 제공하는 JpaRepository 인터페이스가 존재한다. 이제 Entity를 생성했다면 이 객체들을 관리할 수 있는 Repository 클래스를 생성하고 JpaRepository를 상속받아서 CRUD 기능들을 보다 편리하게 사용하며 DB를 관리할 수 있게 되었다.
아래는 Id를 통해서 레포지토리에 저장된 객체 하나를 읽어오는 간단한 예시이다.
MemoRepository
public interface MomoRepository extends JpaRepository<Memo,Long>{}
findById
private Memo findMemo(Long id){
return momoRepository.findById(id).orElseThrow(()->
new IllegalArgumentException("선택한 메모는 존재하지 않습니다.")
);
}
필터란 말 그대로 걸러주는 역할을 하며 보통 사용자 로그인 과정에서 주로 사용된다. 예를 들어 사용자가 같은 요청을 보내도 해당 사용자의 권한에 따라 사용자A는 접근 가능하지만 사용자B는 접근이 불가능 하여 각각 다른 페이지로 응답을 내어줄 수 있게 만드는 것이다.
이번 강의에서는 jwt를 통해 생성된 토큰으로 확인을 하여 사용자 정보를 검증하였다. 당연히 이와 비슷한 기능또한 스프링 프레임 워크에 존재한다!! 다음은 username의 존재유무를 통해 검증하는 예시 코드이다.
package com.sparta.springauth.security;
import com.sparta.springauth.entity.User;
import com.sparta.springauth.repository.UserRepository;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
private final UserRepository userRepository;
public UserDetailsServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("Not Found " + username));
return new UserDetailsImpl(user);
}
}
이제 기본적인 CRUD가 어떻게 작동되는지는 이해가 되었고 직접 구현도 가능할것 같다. 인증 및 인가는 어떤식으로 진행 되는지는 이해가 가는데 직접 구현하는 것은 아직 어렵다!