ํฌ์ธํธ์ปท (Pointcut) ์ด๋์ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ ์ฉํ ์ง ๋ง์ง๋ฅผ ํ๋จํ๋ ํํฐ๋ง ๋ก์ง์
๋๋ค. ํฌ์ธํธ์ปท์ ClassFilter์ MathodMatcher๋ก ์ด๋ฃจ์ด์ง๋๋ค. ClassFilter๋ ํด๋์ค์ ๋ํ ํํฐ๋ง์ ๋ด๋นํ๋ฉฐ, MathodMatcher๋ ๋ฉ์๋์ ๋ํ ํํฐ๋ง์ ๋ด๋นํฉ๋๋ค. ์ด๋๋ฐ์ด์ค (Advice) ํ๋ก์๊ฐ ํธ์ถํ๋ ๋ถ๊ฐ ๊ธฐ๋ฅ์
๋๋ค. ์ด๋๋ฐ์ด์ (Advisor) ํ๋์ ํฌ์ธํธ์ปท๊ณผ ํ๋์ ์ด๋๋ฐ์ด์ค๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค. ์ฝ๊ฒ ์ธ์ฐ๊ธฐ ์ถฉ๊ณ ํ๋ ์ฌ๋(Advisor)์ ๋๊ตฌ(Pointcut)์๊ฒ ์ด๋ค ์ถฉ๊ณ (Advice)๋ฅผ ํด์ผ ํ ์ง ์๊ณ ์์ต๋๋ค. ์ด๋๋ฐ์ด์ค ๋ง๋ค๊ธฐ ๋ค์ ๊ฒ์๊ธ(https://ttl-blog.tistory.com/862)์์ ๋ง๋ ์ด๋๋ฐ์ด์ค๋ฅผ ์ฌ์ฉํ๋๋ก ํ๊ฒ ์ต๋๋ค. class Tim..
๐๏ธ Spring
ํ๋ก์ ํฉํ ๋ฆฌ ์คํ๋ง์ ํ๋ก์ ํฉํ ๋ฆฌ๋ ์ธํฐํ์ด์ค์ ๊ตฌ์ฒด ํด๋์ค์ ๋ํ ํ๋ก์๋ฅผ ๋ชจ๋ ์ ์ฉํ๊ธฐ ์ํด์ JDK ๋์ ํ๋ก์์ CGLIB๋ฅผ ํตํด ์ํฉ์ ๋ง๊ฒ ํ๋ก์๋ฅผ ๋ง๋ค์ด์ค๋๋ค. ์ฆ ๊ฐ๋ฐ์๋ ์ธํฐํ์ด์ค์ธ์ง, ๊ตฌ์ฒด ํด๋์ค์ธ์ง์ ์ ๊ฒฝ์ฐ์ง ์๊ณ ๋, ํ๋ก์๋ฅผ ์ป์ ์ ์๊ฒ ๋๋ ๊ฒ์
๋๋ค. Advice ์คํ๋ง ํ๋ก์ ํฉํ ๋ฆฌ๋ JDK ๋์ ํ๋ก์์ CGLIB๋ฅผ ๋ชจ๋ ์ง์ํ๋ค๊ณ ํ์์ต๋๋ค. JDK ๋์ ํ๋ก์๋ InvocationHandler๋ฅผ ํตํด, CGLIB๋ MethodInterceptor๋ฅผ ํตํด ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ํ๋ก์ ํฉํ ๋ฆฌ๋ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ํด์ ์ด ๋์ ์ค๋ณตํด์ ๋ง๋ค์ด์ผ ํ๋ค๋ ๋ฌธ์ ์ ์ ๊ฐ์ง๊ฒ ๋ฉ๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์คํ๋ง์ Advice๋ผ๋ ๊ฐ๋
์ ๋์
ํ์์ต๋๋ค. ๊ฐ๋จํ JDK ๋..
๊ธฐ์กด Auditing์ ์ฌ์ฉํ ๋์๋ ์๋์ ๊ฐ์ด ์ฌ์ฉํ์์ต๋๋ค. @EntityListeners(AuditingEntityListener.class) @MappedSuperclass public class BaseEntity { @CreatedDate @Column(updatable = false) private LocalDateTime createdDate; @LastModifiedDate private LocalDateTime lastModifiedDate; } ์์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์๋ ํญ์ 2022-03-06T14:12:23.0023123 ๊ณผ ๊ฐ์ ํ์์ผ๋ก ์ ์ฅ๋์๋๋ฐ, ์ด๋ฅผ ์ข ๋ ๊น๋ํ format์ผ๋ก ๋ฐ๊พธ๊ณ ์ถ์ ๋๊ฐ ์์ต๋๋ค. ๊ทธ๋ด ๋๋ @PrePersist, @PreUpdate๋ฅผ ์ฌ์ฉํ์ฌ..
(https://ttl-blog.tistory.com/807)ํด๋น ๊ธ์์ ์๋ก์ด ์ํฐํฐ๋ฅผ ๊ตฌ๋ณํ๋ ๋ฐฉ๋ฒ๊ณผ, save()์ ์๋ ์๋ฆฌ์ ๋ํ์ฌ ์์๋ณด์์ต๋๋ค. ๊ทธ๋ฌ๋ @GenerateValue๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์๋ณ์๋ฅผ ์ง์ ํ ๋นํ๋ ๊ฒฝ์ฐ์๋, ์ด๋ฏธ ์๋ณ์ ๊ฐ์ด ์๋ ์ํ๋ก save()๋ฅผ ํธ์ถํ๊ฒ ๋ฉ๋๋ค. ์ฆ ์ด ๊ฒฝ์ฐ์๋ merge()๊ฐ ํธ์ถ๋๋ ๊ฒ์
๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์๋ Persistable์ ์ฌ์ฉํ์ฌ ์๋ก์ด ์ํฐํฐ์ธ์ง ํ๋ณํ๋ ๋ฐฉ๋ฒ์ ์ง์ ๊ตฌํํ ์ ์์ต๋๋ค. Persistable์ ์๋ฆฌ Persistable์ ์์ ๊ฐ์ ์ธํฐํ์ด์ค์
๋๋ค. save ํธ์ถ ์์๋ SimpleJpaRepository์ save ๋ฉ์๋๊ฐ ํธ์ถ๋๋ฉฐ, ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํ๋์ด ์์ต๋๋ค. ์ด๋ entityInformation์ JpaE..
์คํ๋ง ๋ฐ์ดํฐ JPA๊ฐ ์ ๊ณตํ๋ ํ์ด์ง๊ณผ ์ ๋ ฌ ๊ธฐ๋ฅ์ ์คํ๋ง MVC์ ํจ๊ป ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. http ์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด ์๋์ผ๋ก Pageable ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ฃผ๋๋ฐ ๋ค์์ ๊ทธ ์์์
๋๋ค. @GetMapping("/members") public Page list(Pageable pageable) { Page page = memberRepository.findAll(pageable); return page; } ํ๋ผ๋ฏธํฐ๋ก Pageable ์ ๋ฐ์ ์ ์์ต๋๋ค. ์ค์ ํ ๋น๋๋ ๊ฐ์ฒด๋ PageRequest(org.springframework.data.domain.PageRequest) ์
๋๋ค. ์์ฒญ ํ๋ผ๋ฏธํฐ ํ์ ?page=2&size=3&sort=id,desc&sort=username,des..
์คํ๋ง ๋ถํธ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์๋ฌด๋ฐ ์ค์ ์์ด ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ์ฌ์ฉ ์ @RestController @RequiredArgsConstructor public class MemberController { private final MemberRepository memberRepository; @GetMapping("/members/{id}") public String findMember(@PathVariable("id") Long id) { Member member = memberRepository.findById(id).get(); return member.getUsername(); } } ์ฌ์ฉ ํ @RestController @RequiredArgsConstructor public class MemberC..
Auditing ์ํฐํฐ๋ฅผ ์์ฑ, ๋ณ๊ฒฝํ ๋์ ์๊ฐ๊ณผ, ๋ณ๊ฒฝํ ์ฌ๋์ ์ถ์ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์์ํ๊ฒ JPA๋ง ์ด๋ค๋ฉด @PrePersist ๋ฑ์ ๋ฆฌ์ค๋๋ฅผ ๋ฑ๋กํด์ ๋ฑ๋ก๋๋ ์์ ์ ์๊ฐ๊ณผ ์ฌ๋ ๋ฑ์ ์ ์ฅํ๋๋ก ํด์ผ ํฉ๋๋ค. ์คํ๋ง Data JPA๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์ด๋ฅผ ํธํ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ๊ธฐ๋ฅ์ ์ ๊ณตํด์ค๋๋ค. ์ค์ ์๋ ๋ ์ด๋
ธํ
์ด์
์ ๋ชจ๋ ์ฌ์ฉํด์ฃผ์ด์ผ ํฉ๋๋ค. @EnableJpaAuditing -> ์คํ๋ง ๋ถํธ ์ค์ ํด๋์ค์ ์ ์ฉํด์ผ ํฉ๋๋ค. @EntityListeners(AuditingEntityListener.class) -> ์ํฐํฐ์ ์ ์ฉํฉ๋๋ค. ์์ @EntityListeners(AuditingEntityListener.class) @MappedSuperclass public cl..
์ฌ์ฉ์ ์ ์ ๋ฆฌํฌ์งํ ๋ฆฌ ๊ตฌํ๋ฐฉ๋ฒ ์คํ๋ง ๋ฐ์ดํฐ JPA ๋ฆฌํฌ์งํ ๋ฆฌ๋ ์ธํฐํ์ด์ค๋ง ์ ์ํ๊ณ ๊ตฌํ์ฒด๋ ์คํ๋ง์ด ์๋์ผ๋ก ์์ฑํด์ค๋๋ค. ๊ทธ๋ฌ๋ ์คํ๋ง ๋ฐ์ดํฐ JPA๊ฐ ์ ๊ณตํด์ฃผ๋ ๊ธฐ๋ฅ ์ด์ธ์ ์ถ๊ฐ๋ก ํ์ํ ๊ธฐ๋ฅ์ด ์๋ ๊ฒฝ์ฐ, ์ด๋ฅผ ์์๋ฐ์ ์ง์ ๊ตฌํํ๋ ๊ฒ์ ๋๋ฌด ์ด๋ ต์ต๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ์ฌ์ฉ์ ์ ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ฌ JPA ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ์์๋ฐ์ ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ฌ์ฉ์ ์ ์ ์ธํฐํ์ด์ค public interface MemberRepositoryCustom { List findMemberCustom(); } ์ฌ์ฉ์ ์ ์ ์ธํฐํ์ด์ค ๊ตฌํ ํด๋์ค @RequiredArgsConstructor public class MemberRepositoryImpl implements MemberRepository..