Spring
Spring Builder 패턴 제대로 알고 어노테이션 사용하기 (@AllArgsConstructor, @NoArgsConstructor가 필요한 이유)
처음 스프링으로 개발을 할 때는 생성자를 사용한 객체 생성만 사용했다. 여러 코드를 보다 보니 자연스레 builder 패턴에 대해 알게 되었고 지금은 Builder 패턴으로만 객체를 생성하는 것 같다. 이때 @NoArgsConstructor, @AllArgsConstructor를 @Builder와 함께 항상 작성했는데 원리를 정확하게 알고 싶어 공부할 겸 글을 작성한다. (builder와 생성자 방법의 차이점, builder의 장점 등은 생략한다. ) 어노테이션 없이 builder 사용하기 @Builder를 사용하기 전에 어노테이션 없이 builder 패턴을 사용하는 예제를 확인하겠다 public class User { private final String username; private final St..
@ModelAttribute, @SessionAttribute name 속성 차이
강의를 듣다가 @SessionAttribute를 사용했다. 컨트롤러 매개 변수 단계에서 session을 받아오는 역할을 해주었다. 이때 name 속성을 사용했는데 이것저것 건드려보다 @ModelAttribute와 다른 점을 발견했다. 개인적으로 흥미로운 발견이어서 테스트하는 코드를 작성해 보았다. @ModelAttribute의 name 속성 @ModelAttribute는 사용자의 입력 값과 객체를 바인딩 후 model에 담아준다. name 속성을 지정해주면 그에 맞게 model의 이름이 설정된다. name 속성을 사용하지 않으면 클래스의 첫 글자를 소문자로 바꾼 문자를 name으로 설정한다. => member (@ModelAttribute가 클래스 이름인Member를 member로 바꿔 사용하기에 teh..
[Spring] 나만 보는 스프링 사전(스프링 어노테이션)
이 글은 정보 공유 글이 아닌 스프링 공부하면서 자주 사용할 것 같은 키워드 정리이다. 자세한 설명은 노션에 정리해 두었고 내가 나중에 오랜만에 스프링 할 때 기억 안 날 경우에 사용하기 위해 작성하는 글이다. @slf4j 클래스에 선언하고 log.trace(적고싶은 메시지), log.debug, info, warn, error로 작성 문자열은 + 연산이 아닌 ("my log {}",message) 와 같이 작성. 스프링 설정에 logging.level.hello.springmvc=하고 출력 로그 레벨 작성 httpmethod @GetMapping 같은 것에 consume, produces 속성 매핑 가능. 각각 request 헤더의 content-tpye, accept와 일치해야 한다. @Request..
[Spring JPA] 영속성 컨텍스트 완벽 이해!, 연관 관계 주인 mapping (cascade와 차이?)
spring을 공부하며 Jpa를 자연스레 접하게 되었는데 단어만 아는 수준으로 넘어갔던 영속성 컨텍스트. cascade가 등장하고 연관 관계의 주인과 헷갈리게 되었고 차이점을 알아보다 보니 jpa에 대해서 아는 게 너무 없었다. 그래서 영속성 컨텍스트와 연관 관계 주인을 이해할 때까지 , 의문점이 사라질 때까지 직접 코드를 작성하며 해결하였다. 강의에서 나오는 것을 그대로를 설명하는 것이 절대 아니어서 도움이 많이 될 것 같은 글이다. 개념 설명하고 코드로 다시 한번 설명하겠다. 코드 부분이 진국이라고 생각한다. 바로 시작하겠다. (너무 기본적인 것은 생략한다.) Jpa를 사용하면 DB와 spring 사이에 영속성 컨텍스트라는 것이 생긴다. 영속성 컨텍스트 1차 캐시, 스냅샷, 쓰기 지연 SQL 저장소...
[Spring] JPA란? (간단정리)
지금까지 spring, springboot를 간단하게 여러 번 훑어보았다. 이제 본격적으로 토이프로젝트를 시작하기 전에 간단하게 기초내용들을 한번 정리하려고 시작하려 한다. JPA JPA (Java Persistence API)는 자바 ORM 기술에 대한 API들이다. 인터페이스의 집합체이다. ORM이란 (Object-Relational Mapping) 객체와 관계형 데이터베이스 간의 차이를 중간에서 해결해 주는 기술이다. crud sql을 알아서 처리해 준다. jpa를 사용하기전에는 SQL문을 한줄 한줄 모두 작성해주어야했다고 한다. SQL문을 직접 작성해야하다보니 객체가 데이터 베이스에 추가되거나 수정 등을 하려면 다시 코드를 열어서 모든 SQL을 수정해야 한다. 하지만 jpa를 사용하면 필드만 추가..
[Spring] @JoinColumn & 연관관계 맵핑 @Mappedby (외래키 주인? 연관관계 주인?)
@Entity @Getter @Setter public class Member { @Id @GeneratedValue @Column(name="member_id") private Long id; @NotEmpty private String name; @OneToMany(mappedBy = "member") private List orders = new ArrayList(); } @Entity @Getter @Setter public class Order { @Id @GeneratedValue @Column(name="order_id") private Long id; @ManyToOne @JoinColumn(name="member_id") private Member member; } 현재 위의 코드를 보면..
[Spring] Gradle vs Maven (빌드? 빌드 도구?)
스프링 프로젝트를 시작하려면 빌드 도구 Gradle과 Maven을 선택해야한다. 빌드 도구? 빌드 도구 빌드 도구는 빌드를 위한 도구를 의미한다. 빌드? 빌드 - 우리가 코드를 작성한 소스 코드가 실행할 수 있는 형태로 변환하는 과정을 의미한다. intellij, visual studio에서 코드를 실행하는 것이 아니라 실행만 가능하게 하는 상태로 만들어내는 과정이다. 소스코드를 컴퓨터가 이해할 수 있는 기계어로 번역하여 실행 파일을 만들어내기까지의 단계이다. Gradle과 Maven 역시 빌드 도구이다. 이것들이 필요한 이유는 개발을 할 때 본인이 작성한 코드로만 구성하는 것은 불가능하기 때문이다. 수많은 라이브러리가 필요하다. 이것들을 다운받고 관리하고 컴파일, 빌드 과정까지 통합해서 우리를 도와주기..
[Spring] 웹 스코프 (request) & 프록시
웹 스코프 웹 스코프는 웹 환경에서만 동작한다. 웹 스코프는 소멸될 때까지 관리를 해준다. (PreDestroy 메서드 실행된다.) 4가지 종류가 있는데 첫번째인 request 스코프만 강의에서 설명해주었다. request: HTTP 요청 하나가 들어오고 나갈 때까지 유지되는 스코프, 각각의 HTTP 요청마다 별도의 빈 인스턴스가 생성되고, 관리된다. session: HTTP Session과 동일한 생명주기를 가지는 스코프 application: 서블릿 컨텍스트( ServletContext )와 동일한 생명주기를 가지는 스코프 websocket: 웹 소켓과 동일한 생명주기를 가지는 스코프 request 스코프는 HTTP요청이 들어올 때마다 새로운 빈이 생성된다. 하지만 같은 HTTP의 요청은 하나의 빈..
[Spring] 빈 스코프 (프로토타입)
빈 스코프 빈 스코프의 뜻을 강의 자료에서 가져오자면 빈이 존재할 수 있는 범위이다. 스프링 컨테이너가 언제까지 관리해주는지를 정한다고 생각하면 될 것 같다. 지금까지 사용한 싱글톤 (싱글톤 스코프)은 컨테이너가 생성되고 종료될 때까지 유지된다. 스코프를 설정하는 방법은 @Bean 이나 @Component 위에 @Scope("xxx")를 작성해주면 된다. (꼭 위에 작성해야 된다는 게 아니라 그 위치라는 의미이다. 뭔 말인 줄 알지) 싱글톤은 default값이라 @Scope("singleton")을 굳이 작성해주지 않아도 된다. 프로토타입 포로토토입(prototype) 스코프는 요청이 들어올 때마다 새로운 빈을 생성한다. 클라이언트 4명이 요청을 하면 4개의 빈을 생성해서 각각 다른 빈을 반환한다. 또한..
[Spring] @Qualifier, @Primary & 빈 생명주기 콜백
@Qualifier, @Primary DiscountPolicy 인터페이스는 FixDiscountPolicy, RateDiscountPolicy 라는 구현체 두개를 갖고있다. 만약 두개의 구현체 모두 스프링 컨테이너에 등록이 되어있고 어느 클래스에서 DiscountPolicy를 DI 받아야 하는 상황이라면 FixDiscountPolicy, RateDiscountPolicy 사이에 충돌이 일어날 것이다. 이럴 경우 사용할 수 있는 방법 두 가지를 설명하겠다. @Qualifier DiscountPolicy 구현체들 중 사용하고 싶은 클래스에 @Qualifier("xxxDiscountPolicy) 라고 작성해준다. "" 안은 이름 옵션을 설정해주는 것이다. 그런 후 DI가 발생하는 곳에 동일하게 작성하여 주면..