본문 바로가기

Spring 이해하기18

대체 application.properties 는 어떻게 동작되는 거지? [요약] 1. application.properties 가 인식되는 코드가 변경되었다. 2. config 의 위치에 따른 우선순위 순서가 있다. 3. springboot 는 default 가 .properties 이고, .yml 을 인식하기 위해서는 EnvironmentPostProcessor 를 알아야 한다. 의식의 흐름대로 어떻게 application.properties 를 스프링 부트가 이해할 수 있는지 알아보자. 어느 시점부터 동작 방식이 변경되었다. Spring 2.4.0 부터 application.properties 를 인식하는 것이 스프링부트 코드 내에서 변경되었음을 코드를 통해 확인할 수 있었다. 이전에는 ConfigFileApplicationListener 를 통해서 application.. 2022. 9. 3.
Thymeleaf CheatSheet - 2 (template layout) 공통된 영역은 따로 분리해서 개발해야 한다. 그런 부분에 대한 처리가 바로 템플릿 레이아웃이다. 3가지 방식이 있다. 1. 템플릿 조각 th:fragment 태그의 의미는 다른 곳에 포함되는 코드 조각이라 이해하면 된다. 어떻게 사용하는가? // footer.html 푸터 자리 입니다. 파라미터 자리 입니다. footer.html 에서 2개의 fragment 를 copy 와copyParam 선언했습니다. 그럼 선언한 fragment 를 사용한 부분은 다음과 같습니다. 부분 포함 부분 포함 insert 부분 포함 replace 부분 포함 단순 표현식 파라미터 사용 ~{...} 를 사용 와 같이 footer :: copy 사용 insert 와 replace 의 차이는 현재 태그가 어떻게 되는지에 대한 차이 .. 2021. 9. 6.
Thymeleaf CheatSheet - 1 (basic) Thymeleaf CheatSheet - 1 (basic) 1. 텍스트 - text, utext text vs utext th:text = th:utext = [[...]] vs [(...)] [[...]] = [[${data}]] [(...)] = [(${data})] = ${users[0]['username']} = ${users[0].getUsername()} = Map ${userMap['userA'].username} = ${userMap['userA']['username']} = ${userMap['userA'].getUsername()} = map 으로 선언된 객체일 경우 인텔리제이에서 인식하지 못하는 경우도 있는것 같다.. 2021. 9. 6.
SpringMVC 에서 말하는 MessageConverter 코드로 이해하기 SpringMVC는 어떻게 내가 보낸 요청 메세지를 찰떡같이 알아듣고 Json 등의 내가 원하는 값으로 반환해주는걸까? HTTP 메시지 컨버터에 대해서 조금더 자세히 알아보려고 합니다. 총 2가지로 나눠서 살펴볼 예정입니다. POST 방식의 Request 보낼시, @RequestBody 가 어떻게 Converter 되는지. GET 방식으로 Request 조회시, @ResponseBody가 어떻게 Converter 되는지 확인해볼 예정입니다. MessageConverter 종류 MessageConverter 의 종류를 이해하기 위해서는 먼저 HttpMessageConverter 가 무엇인지 알아봅니다. SpringMVC 에서는 인터페이스로 존재하는데, 아래와 같습니다. package org.springfr.. 2021. 8. 15.
[JPA] JoinColumn vs mappedBy mappedBy 와 @JoinedColumn 에 대해서 알아보기. @Entity public class Company { ... private String name; @OneToMany(mappedBy = "company", orphanRemoval = true, fetch = FetchType.LAZY, cascade = CascadeType.ALL) private List branchs = new ArrayList(); ... } @Entity public class Branch { ... private String branchName; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "companyId", foreignKey = @ForeignKey(.. 2021. 6. 13.
인터페이스 빈 주입을 사용해야 하는 이유 위 내용은 https://youtu.be/C6nsjqrCJq4 백기선님의 유튜브에서 발췌했습니다. 만약 위와 같은 에러가 발생했다라면? *************************** APPLICATION FAILED TO START *************************** Description: The bean 'defaultMyService' could not be injected as a 'com.example.demo.DefaultMyService' because it is a JDK dynamic proxy that implements: com.example.demo.MyService Action: Consider injecting the bean as one of its interf.. 2021. 6. 12.
[JPA] Collection 을 업데이트 할때, add()와 addAll() 을 조심하자. JPA 에서 Collection 을 업데이트 할 때, 다음과 같은 에러를 받았다. o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23505, SQLState: 23505 o.h.engine.jdbc.spi.SqlExceptionHelper : Unique index or primary key violation: "PUBLIC.UK_9NEY9DAVBULF79NMN9VG6K7TN_INDEX_2 ON PUBLIC.LINE(NAME) VALUES 2"; SQL statement: update line set created_date=?, modified_date=?, color=?, name=? where id=? [23505-200] 받았던 이유는 line enti.. 2021. 6. 5.
Spring Data JDBC 가볍게 살펴보기 - 1 Spring Data JPA 마찬가지로, Spring Data 라는 Prefix 가 붙습니다. 여기서 Spring Data 란 무엇일까? 간단하게 Docs 에서 말하는 컨셉을 이해해보자. Spring Data의 핵심은 Repository 이다. 이는 ID가 되는 Type과 Domain Class가 되는 Type을 Argument로 갖는다. 이 인터페이스는 주로 작업할 Type을 캡처하고 인터페이스를 확장하는 인터페이스를 발견하는 데 도움이 되는 마커 인터페이스 역할을 합니다. - docs.spring.io/spring-data/jdbc/docs/current/reference/html/#repositories.core-concepts 아마도 Spring Data 라고 하는 것들은 Repository 가 .. 2021. 5. 9.
Gradlew Command 살펴보기 ./gradlew > Task :help Welcome to Gradle 6.8. To run a build, run gradlew ... To see a list of available tasks, run gradlew tasks To see a list of command-line options, run gradlew --help To see more detail about a task, run gradlew help --task For troubleshooting, visit https://help.gradle.org BUILD SUCCESSFUL in 521ms 1 actionable task: 1 executed 매개변수가 없이 할경우 위와 같은 결과 나옴 ./gradlew tasks ❯ ./g.. 2021. 1. 27.
Gradle 버전 변경하기 이번에 Gradle에 대해서 버전을 변경하는 방법을 알아보자. Gradle을 변경하게 된 이유는, 사용하던 Gradle 6.6.1 버전을 사용할 경우 아래와 같은 문구가 build할 때 계속 발생하기 때문이였습니다. ./gradlew: line 39: cd: "./: No such file or directory Gradle 버전 마다 위와같은 에러가 발생하는 경우가 있었습니다. 이 때는 Gradle 버전을 변경하면 이 문제를 해결할 수 있습니다. Gradle에 대해서 잘 모를 때는 gradle-wrapper.properties에 있는 값을 수정했었습니다. distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=ht.. 2021. 1. 27.
스프링이란 무엇인가? 아래 내용은 토비의 스프링을 읽으며, 일부 내용을 발췌한 것임을 밝힙니다. 스프링이란 무엇인가? 여전히 '스프링을 사용하는 이유가 무엇일까?' 이 질문에 대해서 여타 다른 프레임워크에 반해 도드라지는 특징을 찾지 못했던 것 같다. 물론 IoC/DI 의 강력함으로 타 프레임워크보다 강점으로 둘 수 있지만, 그보다 더 다양한 관점에서 말할 수는 없을까? 가장 쉽게 알려진 정의는 스프링은 아래와 같다. "자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크" 그럼 '애플리케이션 프레임워크'는 무엇인가? 특정 계층이나 기술, 업무 분야에 국한되지 않고 애플리케이션의 전 영역을 포괄하는 범용적인 프레임워크, 애플리케이션 개발의 전 과정을 빠르고 편리하게 효율적으로 진행하는 데 일차적인 목.. 2021. 1. 6.
[JPA] Field or Property access? 원본 - thorben-janssen.com/access-strategies-in-jpa-and-hibernate/ Access Strategies in JPA and Hibernate - Which is better, field or property access? - Thorben Janssen JPA and Hibernate support field-based and property-based access strategies. But what exactly is the difference and which one should you choose? thorben-janssen.com 들어가기 JPA를 활용해 연관관계를 맺을 때, 나도 간과했던 부분이 하나 있었습니다. Entity 의 attributes.. 2020. 12. 13.
@DataJpaTest 흟어보기 Spring JPA에서 Repository 테스트를 하기 위한 애노테이션으로 @DataJpaTest 를 사용합니다. 왜 Repository 를 테스트 해야 하는걸까? 반버논의 도메인 주도설계에서 테스트를 하는 이유는 아래와 같은 이유라고 합니다. "#리파지토리의 테스트를 바라보는 두 가지 방향 1. 리파지토리 자체가 바르게 동작하는지 증명하기 위해서 2. 그들이 생성하는 애그리게잇을 저장하고 기존의 애그리게잇을 검색하기 위해 리파지토리를 사용하는 코드를 테스트한다. 첫번째 유형의 테스트에선 완전한 프로덕션 수준 품질의 구현을 사용해야 한다. 그렇지 않으면 프로덕션 코드가 작동할지 알 수 있는 방법이 없다. 두번 째 유형의 테스트에선 프로덕션 구현을 사용하거나 그 대신 인메모리 구현을 사용할 수 있다." .. 2020. 12. 12.
@Fetch(FetchMode.SUBSELECT) 과 IN subquery 는 왜 느릴까? 들어가기 JPA 를 활용하다가 문제를 하나 맞딱뜨렸습니다. 퇴근하기 10분전, 동료분의 호출로 위 그림처럼 시간이 오래걸리는 경우가 발생했습니다. 처음 보는 코드에서 어디서 발생했는지 알 수 없는 상황에서 겉으로 보기에는 아무런 문제가 없었습니다. 그러던 중, 코드를 살펴보던 중 처음 보는 어노테이션 @Fetch(FetchMode.SUBSELECT) 가 있었습니다. @Fetch(FetchMode.SUBSELECT) 이란? JPA를 활용하다보면, N+1 문제는 늘 발생할 수 있는 문제입니다. N+1 문제를 해결하기 위해 다양한 방법 있습니다. 그리고, 그 가운데 Fetch(FetchMode.SUBSELECT) 이 있습니다. 그럼 이 애노테이션은 어떻게 N+1 문제를 해결할까요? 백기선님의 블로그를 참고하.. 2020. 10. 14.
LazyInitializationException 를 벗어나기 위해서는 어떻게 해야될까? JPA에서 최적의 쿼리를 보내는 방법은 무엇일까? Photo by Jan Antonin Kolar on Unsplash 들어가기 JPA의 연관관계를 사용하다 사용하지 않으니까, 금방 까먹고, 또다시 공부하는 제 모습을 보면서, 이 부분은 어느 정도 정리해야겠다는 마음으로 포스팅을 작성합니다. 이 글은 실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화 학습한 뒤, 일부 내용을 편집했습니다. 리뷰 전체적으로 김영한 강사님의 노하우가 '녹아내려있다' 라는 생각은 강하게 들었습니다. 당연하다고 여겨지는 부분이라도 직접 동작하는 코드로 이해하지 않는다면, 이해하지 않은 것이라고 했습니다. 그런 측면에서 이번 강의는 당연하지만 실행해보지 않았기에 몰랐던 부분을 잘 집어주는 부분이 많았습니다. LazyInitializationException 는 왜.. 2020. 10. 3.
대체 JPA에서 Proxy 로 초기화된다는 말이 뭔데? 들어가기 인프런에서 JPA관련 학습 동영상을 듣다가 LazyInitalization 의 경우, null로 Porxy가 초기화 된다는 말을 했었습니다. 그래서, 코드를 찬찬히 보니 어떤 가짜 객체를 만드는 것처럼 보였습니다. 이건 대체 무엇일까? 라는 고민으로 "다이나믹프록시" 에 대한 학습을 하게 되었습니다. 대부분의 내용은 백기선님의 더 자바, 코드를 조작하는 다양한 방법에서 발췌한 부분을 베이스로, 이를 제가 이해한 방식으로 풀어 적어내려가볼까 합니다. 스프링부트에서 디버깅을 하다 보면 자주 마주치는 이름이 바로 cglib 이라는 라이브러리입니다. 이 라이브러리는 코드를 생성해주는 것이라고 이해하고 있었고, 자세히는 몰랐었습니다. 인터넷에 검색을 해도 생각했던 것 만큼 자세히 나오지는 않았습니다. 그.. 2020. 10. 2.
Spring PSA(Portable Service Abstraction) 란 무엇인가? "잘 만든 인터페이스 하나가 열 클래스 부럽지 않다" PSA = 잘 만든 인터페이스 Spring 에서 제공하는 대부분의 인터페이스는 PSA 입니다. PSA가 적용된 코드라면 확장성이 좋고, 기술에 특화되어 있지 않는 코드를 의미합니다. 트랜잭션(Transaction) 대표적인 예시로 @Transactional > PlatformTransactionalManager 의 인터페이스가 중요하다. PlatformTransactionalManager 의 구현체들이 바뀌더라도 그 PlatformTransactionalManager 의 코드는 변경되지 않습니다. docs.spring.io/spring-framework/docs/current/spring-framework-reference/data-access.htm.. 2020. 9. 1.
Ioc(Inversion of Controller) Ioc(Inversion of Controller) 란 무엇인가? "제어권을 역전시킨다." 라는 말의 의미 0. 들어가며 스프링프레임워크를 비교적 손쉽게 사용하고, Service layer에 퍼사드로서 다양한 객체들을 합쳐 코딩할때쯤 IoC에 대해서 조금더 명확하게 알아야 겠다는 생각이 들었습니다. Inversion of Controller 이라는 말은 간단히 생각하면 제어권을 역전시킨다. 의 의미로 쉽게 받아들여질 수 있습니다. 그러나, IoC에 대해서 다른 사람들은 어떻게 정의내리는지 확인하고, 좀 더 깊은 고찰로 이끌어내보자. 1. Ioc에 대한 간략한 설명 인프런의 백기선님의 강의에서 IoC의 설명을 빌리면, "내가 쓸 놈은 내가 만들어 쓸게" 라는 식의 일반적인 의존성이 뒤집혀진다는 것을 의미합.. 2020. 8. 26.