๐Ÿ๏ธ Spring

ํฌ์ธํŠธ์ปท (Pointcut) ์–ด๋””์— ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์ ์šฉํ• ์ง€ ๋ง์ง€๋ฅผ ํŒ๋‹จํ•˜๋Š” ํ•„ํ„ฐ๋ง ๋กœ์ง์ž…๋‹ˆ๋‹ค. ํฌ์ธํŠธ์ปท์€ ClassFilter์™€ MathodMatcher๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ClassFilter๋Š” ํด๋ž˜์Šค์— ๋Œ€ํ•œ ํ•„ํ„ฐ๋ง์„ ๋‹ด๋‹นํ•˜๋ฉฐ, MathodMatcher๋Š” ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ํ•„ํ„ฐ๋ง์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์–ด๋“œ๋ฐ”์ด์Šค (Advice) ํ”„๋ก์‹œ๊ฐ€ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์–ด๋“œ๋ฐ”์ด์ € (Advisor) ํ•˜๋‚˜์˜ ํฌ์ธํŠธ์ปท๊ณผ ํ•˜๋‚˜์˜ ์–ด๋“œ๋ฐ”์ด์Šค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‰ฝ๊ฒŒ ์™ธ์šฐ๊ธฐ ์ถฉ๊ณ ํ•˜๋Š” ์‚ฌ๋žŒ(Advisor)์€ ๋ˆ„๊ตฌ(Pointcut)์—๊ฒŒ ์–ด๋–ค ์ถฉ๊ณ (Advice)๋ฅผ ํ•ด์•ผ ํ• ์ง€ ์•Œ๊ณ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋“œ๋ฐ”์ด์Šค ๋งŒ๋“ค๊ธฐ ๋‹ค์Œ ๊ฒŒ์‹œ๊ธ€(https://ttl-blog.tistory.com/862)์—์„œ ๋งŒ๋“  ์–ด๋“œ๋ฐ”์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. class Tim..
ํ”„๋ก์‹œ ํŒฉํ† ๋ฆฌ ์Šคํ”„๋ง์˜ ํ”„๋ก์‹œ ํŒฉํ† ๋ฆฌ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ตฌ์ฒด ํด๋ž˜์Šค์— ๋Œ€ํ•œ ํ”„๋ก์‹œ๋ฅผ ๋ชจ๋‘ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ 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..
๋ง ๋ž‘
'๐Ÿ๏ธ Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๊ธ€ ๋ชฉ๋ก (6 Page)