IoC컨테이너란 제어의 역전이라고 불리우며, 모든 객체에 대한 제어권이 바뀌었다는 것을 의미합니다. 스프링에서는 객체 생성 -> 의존성 객체 주입 -> 의존성 객체 메소드 호출 순서로 객체가 만들어지고 실행되어 객체간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있다는 장점이 있습니다.
스프링에서는 외부의 대상이 IoC컨테이너가 되어, 빈을 알아서 주입해주는데 빈들간의 의존관계를 DI를 통해 해결합니다.
Spring IoC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라고 부릅니다.
우리가 알던 기존의 Java Programming 에서는 Class를 생성하고 new를 입력하여 원하는 객체를 직접 생성한 후에 사용했었습니다. 하지만 Spring에서는 직접 new를 이용하여 생성한 객체가 아니라, Spring에 의하여 관리당하는 자바 객체를 사용합니다.
컨테이너에 있는 스프링 빈을 찾아 주입시켜 주는 어노테이션
- @AutoWired
IoC 컨테이너에 있는 참조할 빈을 찾아 주입합니다.- @ComponentScan이라는 어노테이션을 사용하고 패키지를 적어 주면 해당 패키지 아래에 빈으로 등록하려는 어노테이션을 찾아 모두 빈으로 등록해 주는데, 빈으로 등록하려는 어노테이션은 @Component, @Service, @Repository, @Controller, @RestController를 사용합니다
스프링부트에서는 패키지이름Application.java 파일(프로젝트를 만들면 자동으로 생기는 파일)에서 ApplicationContext를 직접 만들어 사용할 필요 없이 @SpringBootApplication이라는 어노테이션을 사용해 @ComponentScan 등 여러 기능을 사용할 수 있다.
어노테이션을 통해 컨테이너에 스프링 빈으로 등록시켜 줄 수도 있습니다.
- @Bean
프로그래머가 컨트롤할 수 없는 외부 라이브러리를 Bean으로 등록하려는 경우에 사용한다. 메소드로 리턴되는 객체를 빈에 등록한다.- @Configuration
클래스에서 1개 이상의 Bean을 등록하고 있음을 명시한다. @Bean 어노테이션을 사용하는 클래스의 경우 반드시 클래스 이름 위에 @Configuration을 함께 사용해주어야 한다.- @Component
프로그래머가 직접 개발한 클래스를 Bean으로 등록하려는 경우에 사용한다. 선언된 클래스를 빈으로 등록한다.
객체를 직접 생성하는 것이 아니라 외부에서 생성한 후 주입받아 사용하는 방법으로, 스프링이 IoC를 실제로 구현하는 방법입니다. 예를 들자면 A 객체에서 B 객체와 C 객체를 의존할 때 A 객체에서 직접 생성하는 것이 아니라 외부에서 생성된 B 객체와 C 객체를 주입시켜 세터 혹은 생성자를 통해 사용하는 것 입니다.
Spring에서는 Controller , Service , Repository라는 3계층으로 분리되는데,
클라이언트와 가장 가까이 맞닿는 부분
Controller란 MVC모델의 하나로 주로 사용자의 요청을 처리 한 후 지정된 뷰(View)에 모델 객체를 넘겨주는 역할을 수행합니다. 요청에 따라 어떤 처리를 할지 결정해주지만, Controller는 단지 결정만 해줄 뿐 실질적인 처리는 서비스(Service)에서 담당합니다.
컨트롤러를 사용하는 이유는 대규모 서비스로 갈수록 처리 해야 할 서비스들이 많아지는데, 이를 하나의 클래스 에서 몰아 처리할 게 아니라 Controller라는 중간 제어자 역할을 하는 것을 만들어 필요한 로직처리를 위한 서비스를 호출하게 됩니다.
즉, 컨트롤러의 역할은 요청에 따라 로직처리를 위한 분기를 담당하고, 사용자에게 서버에서 처리된 데이터를 포함한 View를 리턴합니다.
컨트롤러의 어노테이션으로는 @Contoller 와 @RestController로 나누어지며 @RestController는 자바의 인스턴스를 JSON 형식의 텍스트로 변환할 때 사용합니다.
실제로 작업이 일어나는 단계
Service란 사용자의 요청(request)에 대해 어떤 처리를 할지 결정하는 파트입니다. 즉, Controller에서 전달 받은 사용자의 요청사항에 알맞게 데이터를 가공해서 데이터베이스로 전달하거나, 데이터베이스에서 데이터를 전달 받아 가공하여 유저에게 전달하는 역할을 합니다. Service의 어노테이션은 @Service입니다.
Service에서 나온 결과값을 저장하거나 기존의 저장된 정보를 반환
Repository란 Entity에 의해 생성된 DB에 접근하는 메서드 들을 사용하기 위한 인터페이스로 @Entity라는 어노테이션을 사용하여 데이터베이스 구조를 만들었다면 여기에 CRUD를 할 때 어떻게 할 것인지 정의해줍니다. Repository는 JpaRepository를 상속 받는데, jpa는 인터페이스입니다. 미리 검색 메소드를 정의 해 두는 것으로, 메소드를 호출하는 것 만으로 스마트한 데이터 검색을 할 수 있게 되는 것 입니다.
즉, JpaRepository를 상속 받으면 기본적으로 제공되는 메서드(save().findAll(),get())등을 사용할 수 있게 됩니다.
위에서 언급한 어노테이션도 스프링에서는 중요하게 생각되는 부분중에 하나입니다. 어노테이션을 사용한다면 코드가 깔끔해지고 재사용이 가능하다는 장점이 있습니다.
Spring에서는 어노테이션을 많이 사용합니다. 어노테이션이란 클래스와 메서드에 추가하여 다양한 기능을 부여하는 역할을 합니다. 어노테이션을 활용하여 Spring Framework는 해당 클래스가 어떤 역할인지 정하기도 하고, Bean을 주입하기도 하며, 자동으로 Getter나 Setter를 생성하기도 합니다.
Java에서 어노테이션의 역할으로는 사전상으로는 주석의 의미이지만 Java에서는 주석 이상의 기능을 가지고 있습니다. 어노테이션은 자바 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종입니다. 소스코드에 추가하면 단순 주석의 기능을 하는 것이 아니라 특별한 의미를 부여하거나 기능을 부여하는 등 다양한 역할을 수행할 수 있습니다.
대표적인 어노테이션
@Component
개발자가 생성한 Class를 Spring의 Bean으로 등록할 때 즉, 스프링이 필요 시 자동으로 생성하는 클래스 목록에 추가하는 기능을 가진 어노테이션 입니다.
@Controller / RestController
Spring에게 해당 클래스가 Controller의 역할을 한다고 명시하기 위해 사용하는 어노테이션 입니다.
@RequestParam
URL에 전달되는 파라미터를 메소드의 인자와 매칭시켜, 파라미터를 받아서 처리할 수 있는 어노테이션으로 JSON 형식의 Body를 Java객체로 변환시킵니다.
@RequestBody
Body에 전달되는 데이터를 메소드의 인자와 매칭시켜, 데이터를 받아서 처리할 수 있는 어노테이션으로 클라이언트가 보내는 HTTP 요청 본문을 Java오브젝트로 변환합니다.
@GETMapping
Method = RequestMethod.GET과 같은 역할을 하는 어노테이션 입니다. (데이터를 받아온다.)
@POSTMapping
Method = RequestMethod.POST과 같은 역할을 하는 어노테이션 입니다. (데이터를 생성한다..)
@Setter
Setter method를 생성합니다.
@Getter
Getter method를 생성합니다.
@NoArgsConstructor
기본 생성자를 자동으로 추가해줍니다.
이외에 더욱 많은 어노테이션이 존재하는데, 필요한 어노테이션을 적절히 사용하여 데이터들의 대한 유효조건을 쉽게 파악할 수 있게 됩니다.