스프링 어노테이션? 스프링 프레임워크에서 사용되는 특별한 키워드
어노테이션은 자바 클래스, 메소드, 필드 등에 추가되며, 스프링 어노테이션은 스프링 프레임워크에서 구성 요소를 정의하고 구성하는 데 사용된다.( 가독성이 좋음)
@SpringBootApplication => spring.start사이트에 들어가서 내가 설정한 프로젝트명으로 나오는 자바 파일이있는데 이 어노테이션이 붙은 파일이 스프링을 돌리는 중추 역할을 한다. @SpringBootApplication 애너테이션을 통해 스프링부트의 모든 설정이 관리된다.
@GetMapping 애너테이션은 요청된 URL과의 매핑을 담당한다.
( 내가 크롬에 들어가서 http://localhost:8080/hello 요청을 하면 스프링 부트는 /hello URL과 매핑되는 index 메서드를 MainController 클래스에서 찾아 실행한다.)
@ResponseBody 애너테이션은 URL 요청에 대한 응답으로 문자열을 리턴하라는 의미이다.
@Autowired 애너테이션은 스프링의 DI 기능으로 객체를 스프링이 자동으로 생성해 준다.
#DI(Dependency Injection) => 스프링이 객체를 대신 생성하여 주입한다.
(상세하게==> 객체를 주입하기 위해 사용하는 스프링의 애너테이션이다. 객체를 주입하는 방식에는 @Autowired 외에 Setter 또는 생성자를 사용하는 방식이 있다. 순환참조 문제와 같은 이유로 @Autowired 보다는 생성자를 통한 객체 주입방식이 권장된다. 하지만 테스트 코드의 경우에는 생성자를 통한 객체의 주입이 불가능하므로 테스트 코드 작성시유용하다.
#순환참조?(아래의 코드 예시를 통해서)@Component public class A { @Autowired private B b; // ... } @Component public class B { @Autowired private A a; // ... }
현재 코드에서는 A 객체와 B 객체가 서로를 참조하고 있습니다. A 객체는 B 객체에의존하고 있으며, B 객체는 A객체에 의존하고 있습니다. 이 상황에서 초기화하려고 하면 순환 참조 예외가 발생합니다. 위에서 언급한 생성자를 통한 객체 주입 방식을 코드로 구현해본다면
@Component public class A { private final B b; @Autowired public A(B b) { this.b = b; } // ... } @Component public class B { private final A a; @Autowired public B(A a) { this.a = a; } // ... }
결론!!! 스프링의 의존성 주입(Dependency Injection) 방식 3가지
- @Autowired 속성 - 속성에 @Autowired 애너테이션을 적용하여 객체를 주입하는 방식
- 생성자 - 생성자를 작성하여 객체를 주입하는 방식 (권장하는 방식)
- Setter - Setter 메서드를 작성하여 객체를 주입하는 방식 (메서드에 @Autowired 애너테이션 적용이 필요하다.)
@RequiredArgsConstructor는 롬복이 제공하는 애너테이션으로 final이 붙은 속성을 포함하는 생성자를 자동으로 생성하는 역할을 한다.
@RequestMapping("") = 컨트롤러의 요청 매핑을 설정하기 위한 어노테이션 중 하나입니다.
예를들어서@Controller @RequiredArgsConstructor public class MainController { @GetMapping("/hello/list") public String method1() { //~~~ } @GetMapping("/hello/detail") public String method1() { //~~ } }
라는 클래스가 있다고 하자 이 때 2개의 url주소 프리픽스로 매핑하고있다
1. @GetMapping("/hello/list")
2. @GetMapping("/hello/detail")
1번과 2번은 둘다 /hello 이라는 공통 url프리픽스를 가지고 있다. 이때 @RequestMapping("/hello")어노테이션을 사용해준다면@Controller @RequiredArgsConstructor @RequestMapping("/hello") public class MainController { @GetMapping("/list") public String method1() { //~~~ } @GetMapping("/detail") public String method1() { //~~ } }
공통되는 hello부분을 @RequestMapping("/hello")으로 처리해줄 수 있다.
@RequiredArgsConstructor(Lombok에서 제공) : final이 붙은 필드를 매게변수로 받는 생성자를 만듬
즉 아래의 코드처럼 쓰게되면 @RequiredArgsConstructor어노테이션 때문에//1번코드 import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class MyClass { private final int id; private final String name; private int age; }
2번코드를 쓰지않아도 암묵적으로 2번코드가 생성된다고 보면된다
//2번코드 public MyClass(int id, String name) { this.id = id; this.name = name; }