스프링 실전 2-1
📙 DI(Dependency Injection)
DI(Dependency Injection)이란?
IoC(Implementation of the Inversionof Control)또는 DI는 오브젝트가 자신의 의존성을 정의하는 작업이다. 클래스간의 의존관계를 스프링 컨테이너가자동으로 연결해주는 것
컨테이너는 bean을 만들면 의존성을 주입을 하게된다.
Beans
org.springframework.beans와 org.springframework.context 패키지는 스프링 프레임워크의 IoC 컨테이너의 기본이며, BeanFactory 인터페이스는 어떤 객체든 관리가 가능할 수 있도록 환경설정을 제공한다.
Factory 메소드 개념
References
Core Technologies
In the preceding scenario, using @Autowired works well and provides the desired modularity, but determining exactly where the autowired bean definitions are declared is still somewhat ambiguous. For example, as a developer looking at ServiceConfig, how do
docs.spring.io
[Spring] @Autowired 와 DI 개념 정리
[Spring] @Autowired 와 DI 개념 정리
인트로 안녕하세요 :) 오늘은 Spring 프레임워크의 @Autowird 어노테이션, 이를 설명하기 위한 DI개념에 대해 정리하겠습니다. 목차 1) DI(Dependency Injection) 개념 2) @Autowired 개념 3) @Autowired 와 @Resource 4) @
life-with-coding.tistory.com
JPA 어노테이션
@ManyToMany
다대다 관계) 실무에서 사용하면 안된다. 중간에 테이블 수정사항이 생기면 어려움
@Autowired
@Autowired는 필드주입이라는 개념이다.
🤔Autowired를 선언한 객체 같은 경우에는 따로 생성자를 이용해서 객체를 생성하지 않더라도 그대로 쓸 수 있던데, 그런 용도인 걸까??
Injection 하는 역할이지만 밑에 처럼, argsconstructor나 @Builder 어노테이션 등과 같은 생성자 injection이 추세라고 한다.
@Embeddable
@Embeddable 은 @Embedded랑 같이 쓰이게 되는 어노테이션이다.
- @Embeddable은 값 타입을 정의할
- @Embedded는 사용할 때
장점
- 코드의 재사용도
- 높은 응집도
References
[JPA] @Embedded , @Embeddable란 무엇이며 언제 사용할까? 🤔
오늘은 @Embedded는 무엇이며 언제 어떻게 사용하는지에 대해 알아보자. 바로 시작해보자. 🔥 회원 엔티티가 다음과 같다고 가정해보자. 회원 엔티티는 이름, 도시, 주소 번지, 주소 우편번호를 가
dandev.tistory.com
@Controller @Service @Repository @Entity
클래스에 명시하게 되면 Bean 객체로 등록하게 되며, @Autowired에 의해 탐색이 되어진다.

@NoArgsConstructor @RequiredArgsConstructor @AllArgsConstructor
너네는 뭐 때문에 있는거야?
Constructor는 일단 생성자 개념이다.C++에서 객체지향을 처음 배울 때, 클래스에서 생성하는 메서드 역시 생성자인 것을 기억한다면, 어째서 같은 객체지향언어인 자바를 사용하는 스프링에선 따로 생성자를 만들지 않는 것이 의문일 것이다. 배울 때는 @Autowired나 @Constructor 어노테이션을 쓰기 때문에 굳이 생성자를 만들지 않았다.
그러면 예시를 보자...
일단 오피셜을 최대한 참고하면서 쓰는 게 중요하기 때문에, 롬복의 constructor 문서 및 다른 분의 블로그를 가져왔다.
https://projectlombok.org/features/constructor
@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
projectlombok.org
https://siahn95.tistory.com/170
[Lombok] 공식 문서를 통해 알아보는 @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor + 사용시 주
Spring과 Lombok을 사용한다면 꼭 알고 있어야 하는 생성자 관련 어노테이션들이다. 아래 Lombok 공식 문서와 블로그를 참고로 글을 작성하였다. - @NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor - L
siahn95.tistory.com
@NoArgsConstructor
이 경우에는 파라미터가 없는 생성자를 만들어낸다. 예시에도 나와있는 것처럼
@NoArgsConstructor
public static class NoArgsExample {
@NonNull private String field;
}
라는 코드는 곧 바닐라 자바로 치환하자면
public static class NoArgsExample {
@NonNull private String field;
public NoArgsExample() {
}
이렇게 파라미터가 없는 생성자가 된다.
@NonNull 같은 경우에는 null check를 하는 어노테이션으로 null 값이 들어오면 예외처리를 한다. -> 물론 @NoArgsConstructor(force=true)를 이용하여 모든 필드를 null / false/ 0으로 채우는 옵션도 있지만, final 변수가 아닌 이 어노테이션에는 해당이 되지 않으므로 개발자가 나중에 할당해줘야 한다.
@RequiredArgsConstructor
그렇다면... NonNull인 인자는 어떻게 넣어
이 어노테이션을 넣으면 해결? 할 수 있다. 그리고 그 방식을 이해하기 위해서는 먼저 final이라는 변수타입을 먼저 알아야 한다. 제타위키에서 끌어온 설명을 첨부한다.
Java final 클래스/메소드
- final 키워드는 클래스(class), 메소드(method), 변수(variable)에 적용할 수 있다.
- 클래스에 final을 붙이면 상속 불가
- 메소드에 final을 붙이면 override 불가
- 변수에 final을 붙이면 수정 불가
요약하자면 final을 가진 객체의 경우에는, 생성자가 객체를 생성할 시 초기화가 반드시 필요하다.
그리고 @RequiredArgsConstructor는 필드가 선언된 순서로 final 변수와 NonNull 필드를 파라미터로 가진다
@AllArgsConstructor
이름을 보면 알다시피, 모든필드를 파라미터로 가지는 생성자를 만드는 어노테이션이며, 파라미터의 순서는 선언된 필드의 순서를 따르게 된다.
문제점
필드가 선언된 기준으로 파라미터 순서를 받다보니, 필드의 위치를 수정만 해줘도 오류가 발생한다.
@AllArgsConstructor
class Order{
private int count;
private int time;
}
Order order = new Order(30,12);
이런 식이면 30은 count , 12는 time이 된다. 하지만 밑에처럼 필드 순서를 바꾸게 되면
@AllArgsConstructor
class Order{
private int time;
private int count;
}
Order order = new Order(30,12);
30은 time, 12는 count가 되버린다.
그러므로, field 순서로 파라미터 순서를 정하는 @AllArgsConstructor 와 @RequiredArgsConstructor 는 사용을 권장하고 있지 않다!
그래서 생성자를 직접 만들고, Builder 어노테이션을 사용하는 방식이 추천되기도 한다.
public class Order {
private int cancelAmount;
private int orderAmount;
@Builder
private Order(int cancelAmount, int orderAmount) {
this.cancelAmount = cancelAmount;
this.orderAmount = orderAmount;
}
}
// field 순서를 변경해도 에러가 없다.
Order order = Order.builder().orderAmount(5).cancelAmount(4).build();
🤔 그러면 Builder는 바닐라 생성자에 어떤 기능을 제공하고 있을까? 찾아봐야겠다
@Runwith : Junit 실행할 때 spring이랑 엮어줌
@SpringBootTest: Spring 컨테이너 안에서 테스트를 실행 → 없을 시 스프링 기능들이 먹히지 않음
레퍼런스
[Spring] @Autowired 와 DI 개념 정리
[Spring] @Autowired 와 DI 개념 정리
인트로 안녕하세요 :) 오늘은 Spring 프레임워크의 @Autowird 어노테이션, 이를 설명하기 위한 DI개념에 대해 정리하겠습니다. 목차 1) DI(Dependency Injection) 개념 2) @Autowired 개념 3) @Autowired 와 @Resource 4) @
life-with-coding.tistory.com
Trouble Shooting
- can not find symbol
- java.lang.NullPointerException
- Junit5를 쓸 때는 테스트 어노테이션의 경우엔 import org.junit.jupiter.api.Test;를 써야함. 그리고 Runwith 없어야 함
- java.lang.IllegalStateException: Failed to load ApplicationContext
- @WebAppConfiguration 추가 (X)
- @MockBean 추가 (X)
- 결과 다른 경로에 동일한 레포지터리가 있었고 둘 다 동시에 spring bean에 포함되는 바람에 생긴 오류… 허무허무