먼저 빈(Bean)에 대해 알아보자.
빈(Bean)
스프링(Spring) 컨테이너가 관리하는 자바 객체를 빈(Bean)이라 한다.
스프링의 특징에는 제어의 역전(IoC)가 있다.
지금까지 사용자가 new연산을 통해 객체를 생성하고 메소드를 호출했지만 제어의 역전이 적용 된 경우에는 객체의 생성과 사용자의 제어권을 스프링에게 넘긴다.
사용자는 직접 new를 이용해 생성한 객체를 사용하지 않고, 스프링에 의하여 관리당하는 자바 객체를 사용한다. 이 객체를 '빈(bean)' 이라 한다.
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
회원 컨트롤러가 회원 서비스와 회원 리포지토리를 사용할 수 있게 의존관계를 설정한 것이다.
- 생성자에 @Autowired가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어준다. 이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI(Dependency Injection), 의존성 주입이라한다.
스프링 빈을 두가지 방법으로 등록할 수 있는데,
- 컴포넌트 스캔과 자동 의존관계 설정
- 자바 코드로 직접 스프링 빈 등록하기
@Component 어노테이션이 있으면 스프링 빈으로 자동 등록된다.
@Controller, @Service, @Repository도 컴포넌트 스캔이 안에 달려있기 때문에 스프링 빈으로 등록된다.
스프링 빈 등록은 @Component, 연결은 @Autowired 라고 볼 수 있다.
참고: 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만 등록해서 공유한다) -> @Configuration을 통해 수동으로 등록 가능
따라서 같은 스프링 빈이면 모두 같은 인스턴스다.
@Controller
1. @Controller 어노테이션의 역할
- @Controller 어노테이션은 말 그대로, 해당 클래스가 웹 애플리케이션의 컨트롤러임을 나타낸다.
- 스프링 컨테이너는 @Controller 어노테이션이 지정된 클래스를 빈으로 등록하고, 요청을 해당 컨트롤러에 매핑하여 처 리한다.
- @Controller 어노테이션은 클라이언트의 요청을 처리하는 비즈니스 로직과 뷰를 결합하여 전체적인 동작을 제어한다.
2. @Controller 어노테이션의 사용 방법
- @Controller 어노테이션이 지정된 클래스는 일반적으로 HTTP 요청을 처리하기 위한 메소드를 포함한다.
- 각 메소드는 @RequestMapping 어노테이션과 함께 사용하여 특정 URL 패턴에 대한 처리를 정의한다.
- @RequestMapping 어노테이션을 사용하여 요청 URL과 해당 메소드를 매핑시키고, 메소드는 요청을 처리하고 필요한 로직을 수행한 후에 응답을 생성한다.
- 컨트롤러 메소드에서는 ModelAndView, Model, ResponseEntity 등을 반환하여 응답 데이터와 뷰 정보를 제공한다.
3. @Controller 어노테이션의 추가 기능
- @PathVariable 어노테이션을 사용하여 경로 변수를 추출하고 활용할 수 있다.
- @RequestParam 어노테이션을 사용하여 요청 파라미터를 추출하고 활용할 수 있다.
- @ModelAttribute 어노테이션을 사용하여 요청 데이터를 객체에 바인딩하고, 자동으로 모델에 추가할 수 있다
4. @Controller 어노테이션의 예시
@Controller
@RequestMapping("/products")
public class ProductController {
@Autowired
private productService productService;
@RequestMapping("/{id}")
public ModelAndView getProduct(@PathVariable("id")int id) {
Product product = productService.getProductById(id);
ModelAndView modelAndView = new ModelAndView("productView");
modelAndView.addObject("products", products);
return modelAndView;
}
}
위의 예시에서는 "/products"로 시작하는 URL에 대한 요청을 처리하기 위한 컨트롤러이다.
@RequestMapping 을 사용하여 각 요청 URL과 해당 메소드를 매핑하고, ProductService를 이용해 비즈니스 로직을 수행한다.
* DI에는 필드 주입, setter 주입, 생성자 주입 3가지 방법이 있고
DI (Dependency Injection)
의존대상 B가 변하면, 그것이 A에 영향을 미친다. (이일민, 토비의 스프링 3.1)
public class A {
private B b = new B();
}
A라는 클래스가 있고, 이 클래스는 B라는 클래스를 필드로 가질때 B에 final 필드가 추가되는 변경이 일어난다면
new B()부분에서 컴파일 에러가 난다. B 내부의 변경이 일어났는데, A에도 영향을 미치게 된것이다.
이런 경우를 A가 B에 의존한다. 라고한다. 그렇다면 의존성 주입이란, 의존성을 외부에서 주입해준다는 의미가 될것이다. 예를 들어 다음과 같은 코드이다.
public class A {
private B b;
public A(B b) {
this.b = b;
}
}
B가 변경되면 A의 내용도 변경되지만, 의존 대상을 직접 생성하는 것이 아닌 외부로 부터 주입을 받는다.
의존성을 주입하는 방법에는 세가지가 있다.
생성자 주입(Constructor Injection)
public class A {
private B b;
public A(B b) {
this.b = b;
}
}
Setter 주입(Setter Injection)
public class A {
private B b;
public void setB(B b) {
this.b = b;
}
}
인터페이스 주입(Interface Injection)
public interface BInjection {
void inject(B b);
}
public A implements BInjection {
private B b;
@Override
public void inject(B b) {
this.b = b;
}
}
그렇다면 왜 DI를 써야하는가?
- 의존성이 줄어든다 (변경에 덜 취약해진다.)
- 모의 객체를 주입할 수 있기 때문에 단위 테스트가 쉬워진다.
- 가독성이 높아진다.
- 재사용성이 높아진다
'🍀Spring > 기본' 카테고리의 다른 글
[Spring] 예제 만들기 - 객체 지향 원리 적용 (0) | 2024.07.19 |
---|---|
[Spring] 예제 만들기 (0) | 2024.07.13 |
[Spring] 스프링이란? (0) | 2024.07.13 |
테스트 코드 - @BeforeEach, @BeforeAll, @AfterEach, @AfterAll (0) | 2024.07.06 |
스프링 웹 개발 기초 (0) | 2024.07.06 |