위의 태그들은 나중에 찾아보기 쉽게 하기 위해 다소 난잡하지만 저렇게 해 두기로 하자.
숙련주차 학습을 시작했는데, 어렵다!
확실한 건 복습을 꼭 해야 한다는 것.
챌린지반 다른 분들은 똑똑한 사람들이 많아 보인다.
나도 챌린지반 신청할 때의 마음가짐을 잊지 말자.
깃허브
https://github.com/wkdehf217/JavaPractice/tree/main/memo
https://github.com/wkdehf217/JavaPractice/tree/main/jpa-core
Entity의 상태
비영속과 영속 상태
비영속은 그냥 관리받기 전
persist를 통해 영속성 컨텍스트로 전환
준영속상태?
detached : 영속성 컨텍스트에 의해 관리되다가 분리된 상태
detach / clear / close 이 3개의 메서드에 의해 전환됨
detach : 분리
clear : 껍데기만 남기고 내용만 비움 (비우고 재사용)
close : 완전히 종료
merge : 다시 영속상태로 바꾸는 방법
비영속 상태의 Memo와
merge를 통해서 받아온 mergedMemo는 서로 상태가 다르다
mergedMemo는 새로 받아온 메모니까 insert로 인해 영속 상태
가지고 오고 합치고, 없으면 새로 insert ... 깃허브와 비슷하다고 보면 될듯
SpringBoot 의 JPA
gradle에서 memo 프로젝트의 jdbc 삭제..
Hibernate 가져옴
application.properties 의 spring.jpa.hibernate.ddl-auto=update 옵션
변경된 부분만 적용한다
이제는 jpa를 배웠으니까 Memo class -> Entity로 만듦
Springboot에서는 EntityManeger와 EntityManegerFactory 자동 생성
jpa는 DB의 트랜잭션 개념을 가져와서 사용하고 있지
그럼 Spring에서는 어떻게 하느냐?
-> @Transaction
수정하려면 Transaction 상태가 필요하지만 지금 적용이 안되어있기 때문에 (@Transaction이 없으니까) 메모 생성 실패
! 1차 캐시 저장, 변경감지 등등 다 영속성 컨텍스트에서 이루어지는데
그걸하려면 Transaction이 필요함 => 생명주기 일치
트랜잭션 전파(propagation)
MemoRepository를 @Autowired를 통해 주입받아옴
자식의 Transaction이 끝나도 commit이 날라가지 않고, 부모의 Transaction이 끝나야 commit이 됨
= 자식 메서드의 Transaction이 부모의 Transaction에 합쳐졌기 때문
만약 부모가 Transaction이 없다면?
= 자식의 Transaction이 끝나자마자 commit
Spring Data JPA
등록하는법 : extends JpaRepository<T, ID>를 통해 class -> interface로 만듦
제네릭스..
return memoRepository.findAll().stream().map(MemoResponseDto::new).toList();
: MemoResponseDto 생성자중에서 Memo를 파라미터로 가지고 있는 생성자를 찾아서 리스트로 변환
Optional 처리 : orElseThrow(null 체크)
: 만약 메모가 null값이라면 Throw를 던진다
update / delete
memoRepository 내부에 이미 정의되어있음, 인터페이스로 상속받았기 때문에
들어가는 인자 변경함
변경감지 <- 영속성 컨텍스트 <- Transaction이 걸림
updateMemo 부분 Transaction 주석 처리해보면 알 수 있음
JPA Auditing 적용하기
메모장 프로젝트에서 시간이 적용된다고 생각
원래 DateTime 넣으려면 변수 생성 -> 다른 클래스 로직마다 넣어줌
근데 JPA는 클래스 하나 만들어서 어노테이션(@) 달아주면 알아서 해준다
@MappedSuperclass + abstract
Timestamped를 상속받는 클래스는 createdAt이랑 modifiedAt을 가지게 된다
@EntityListeners : 시간달아주기
Memo entity 수정(private 멤버변수 추가)
메인에 @EnableJpaAuditing 달아주기!
Query Methods
메서드 이름으로 SQL을 생성할 수 있는 기능
ex) List findAllByOrderByModifiedAtDesc();
return memoRepository.findAll().stream().map(MemoResponseDto::new).toList();
-> return memoRepository.findAllByOrderByModifiedAtDesc().stream().map(MemoResponseDto::new).toList();
2주차 숙제
@RequestParam 생략 가능
Param 넣는거만 다시 생각, 나머지는 잘 했음
Bean 객체 수동 등록
언제 등록하느냐?
보통은 다 자동으로 하지만
기술적인 문제나 공통적인 관심사를 처리할 때
= 기술 지원 Bean <> 비즈니스 Bean
비밀번호 암호화 하는 경우를 예시로 듬
BCrypt : 비밀번호를 암호화 해주는 Hash함수
주입 주입..
matches를 통해 비교
같은 타입의 Bean이 2개?
인터페이스 또한 주입 가능. 자바의 인터페이스 다형성의 원리
메모 레포지토리 또한 인터페이스(jpa 레포지토리 상속)
인터페이스를 만들고 / 그 구현체 2개를 만들고 / @Autowired하고 / Bean으로 등록을 하면
오류가 난다
같은 타입의 Bean객체가 1개 이상 : 어떤것을 등록해야할지 모르겠다
인증과 인가
Authentiaction : 인증
실제 유저인지 확인 ( 로그인 )
Authorization : 인가
유저가 접근 가능한지 허가 확인 ( 회원/비회원)
비연결성 : 서버와 클라이언트가 연결이 되어있지 않다
리소스를 절약하기 위해서
무상태 : 서버는 클라이언트의 상태를 저장하고 있지 않다
쿠키 - 세션 방식의 인증
쿠키 : 토큰 저장소
세션 : 인증 정보(ID)
쿠키와 세션
쿠키 다루기
띄어쓰기가 있으면 쿠키가 저장이 안 됨 -> encoding으로 공백 처리
Servlet에서 만들어준 Response 객체에다 쿠키를 담아주면 클라이언트한테 반환이 된다
@CookieValue : Pathvalue같은 기능
세션 다루기
HttpServletRequest 받아와서 요청 세션에서 getSession(true) : 그 세션을 생성해서 사용
없으면 null 반환
session.setAttribute 해서 value 넣어줌
get은 session.getAttribute
JWT란
챌린지반 2일차 ( AOP, Intercepter, Advice, Spring security, Proxy)
AOP
비즈니스 로직을 분리하기 위해 씀
AOP(개념) = 필터, 관심사의 분리 프로그래밍 : 공통 로직을 분리해서 코딩할 수 있는 방식
특정한 Controller 전에 꼭 실행하는 객체
Controller 들어가기 전에 AOP 세팅된 거 먼저 훑는다
필터, 인터셉터, 어드바이스 등등(기능) : 개념을 반영한 기능
인터셉터 : 인코딩. 데이터 조작이 더 쉬움
AOP : 공통로직 로깅
인증처리는 Spring 밖에서 하고 들어오는게 좋다
-> Spring security
비즈니스 로직 마다 로깅 전략이 다르면 aop에서 어떻게 구현해요?
-> 실행 조건을 바꿔준다.
인터셉터를 써서
accessToken과 같이 인가 처리가 Interceptor에서 처리하는건가요?
-> Spring security 또는 filter
조건을 사용할 때는 spel을 사용하나요?
-> 명확하게 갈래가 나뉘어지면 쓰긴 하는데
거기서 또 갈래로 나뉘는 경우가 많아서 다른걸 씀
튜터님은 sqel으로 분리 하고, 여러 advice로 나누는
AOP는 추상적인 개념이지만 실질적인 의미는 컨트롤러 진입 전에 공통처리를 지칭한다 이렇게 이해해도 괜찮을까요? 용어 자체의 느낌은 자바 프로그래밍을 할 때 공통적인 부분들을 util로 묶어서 사용하는 방식인 것 같기도 하네요
-> 맞다
proxy : AOP를 부르도록 loggingAOP.log 같은 방식으로 실행되고 있는 콛 위에 한줄 추가 해 준다
@Before, @After 어노테이션을 달아준다?
어 위에 그림으로 봤을때
Filter와 Interceptor와 AOP는 로직실행 전 공통된 걸 모아둔것을 말하는데 각 역할에 따라 분류해 놓은 것이 맞나요?
-> 관심사의 분리를 달성한다라는건 똑같고 구현되어 있는 방식만 다르다
ex) 인증을 걱정하지 않으려고(프로그래머가 편하려고) 미리 해놓는거같은 느낌!!
강의자료 링크
https://uncovered-decade-0f3.notion.site/Spring-Deep-Dive-66500687d7b2488693c34b105ab4c193