Spring 이란? Spring boot, Bean, 어노테이션

최동민·2022년 6월 5일
0

Spring 수업정리

목록 보기
15/47

1. 스프링(Spring)이란?

1.1 스프링의 개념

Spring은 무엇일까요? 스프링은 자바 기반의 웹 어플리케이션을 만들 수 있는 프레임워크입니다. spring.io 사이트에서 확인하면 스프링 프레임워크는 현대 자바 기반의 엔터프라이즈 어플리케이션을 위한 프로그래밍 및 Configuration Model 제공한다라고 언급하고 있습니다.

Python을 이용한 Django, Ruby를 이용한 Ruby on Rails, Javascript를 이용한 Node.js 기반의 웹 서버 개발과 같이 Java 개발자들은 Spring을 사용하여 웹 서비스를 만들 수 있습니다. Spring 은 수많은 국내 기업과 해외 기업에서 매우 많은 서비스를 만들 때 사용되고 있습니다. 자바 백엔드 개발자는 웹 애플리케이션을 개발할 때, 대부분 스프링을 사용한다고 합니다.

1.2. 스프링의 특징

Spring의 특징들은 아래와 같습니다.

Spring은 자바 객체와 라이브러리들을 관리해주며, 톰캣과 같은 WAS 가 내장되어 있어 자바 웹 어플리케이션을 구동할 수 있습니다.
Spring은 경량 컨테이너로 자바 객체를 직접 Spring 안에서 관리합니다. 객체의 생성 및 소멸과 같은 생명 주기(Life cycle)을 관리하며, Spring 컨테이너에서 필요한 객체를 가져와 사용합니다.
Spring의 가장 큰 특징으로 IOC와 DI가 많이 언급됩니다. IOC와 DI의 간단한 개념은 아래와 같습니다.

제어의 역전 (IOC, Inversion Of Control)

일반적으로 처음에 배우는 자바 프로그램에서는 각 객체들이 프로그램의 흐름을 결정하고 각 객체를 직접 생성하고 조작하는 작업(객체를 직접 생성하여 메소드 호출)을 했습니다. 즉, 모든 작업을 사용자가 제어하는 구조였습니다. 예를 들어 A 객체에서 B 객체에 있는 메소드를 사용하고 싶으면, B 객체를 직접 A 객체 내에서 생성하고 메소드를 호출합니다.
하지만 IOC가 적용된 경우, 객체의 생성을 특별한 관리 위임 주체에게 맡깁니다. 이 경우 사용자는 객체를 직접 생성하지 않고, 객체의 생명주기를 컨트롤하는 주체는 다른 주체가 됩니다. 즉, 사용자의 제어권을 다른 주체에게 넘기는 것을 IOC(제어의 역전) 라고 합니다.
요약하면 Spring의 Ioc란 클래스 내부의 객체 생성 -> 의존성 객체의 메소드 호출이 아닌, 스프링에게 제어를 위임하여 스프링이 만든 객체를 주입 -> 의존성 객체의 메소드 호출 구조입니다. 스프링에서는 모든 의존성 객체를 스프링이 실행될때 만들어주고 필요한 곳에 주입해줍니다.

의존성 주입 (DI, Dependency Injection)

어떤 객체(B)를 사용하는 주체(A)가 객체(B)를 직접 생성하는게 아니라 객체를 외부(Spring)에서 생성해서 사용하려는 주체 객체(A)에 주입시켜주는 방식입니다. 사용하는 주체(A)가 사용하려는 객체(B)를 직접 생성하는 경우 의존성(변경사항이 있는 경우 서로에게 영향을 많이 준다)이 높아집니다. 하지만, 외부(Spring)에서 직접 생성하여 관리하는 경우에는 A와 B의 의존성이 줄어듭니다.

2. Spring Boot란?

스프링 부트(Spring Boot)는 스프링(Spring)을 더 쉽게 이용하기 위한 도구라고 볼 수 있습니다. 스프링 이용하여 개발을 할 때, 이것저것 세팅을 해야 될 요소들이 많습니다. 여러가지를 세팅해야되는 진입 장벽이 존재하여 Spring 을 처음 배우려는 사람들은 중도에 그만두는 경우가 많다고 합니다. Spring Boot는 매우 간단하게 프로젝트를 설정할 수 있게 하여, Spring 개발을 조금 더 쉽게 만들어주는 역할을 하고 있습니다.


1. 스프링 빈(Spring Bean)이란?

(부가 설명)
Spring IoC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라고 부릅니다.

우리가 알던 기존의 Java Programming 에서는 Class를 생성하고 new를 입력하여 원하는 객체를 직접 생성한 후에 사용했었습니다. 하지만 Spring에서는 직접 new를 이용하여 생성한 객체가 아니라, Spring에 의하여 관리당하는 자바 객체를 사용합니다. 이렇게 Spring에 의하여 생성되고 관리되는 자바 객체를 Bean이라고 합니다. Spring Framework 에서는 Spring Bean 을 얻기 위하여 ApplicationContext.getBean() 와 같은 메소드를 사용하여 Spring 에서 직접 자바 객체를 얻어서 사용합니다.

2. Spring Bean을 Spring IoC Container에 등록하는 방법

2.1. 자바 어노테이션(Java Annotation)을 사용하는 방법

JAVA에서 Annotation 이라는 기능이 있습니다. 사전상으로는 주석의 의미이지만 Java 에서는 주석 이상의 기능을 가지고 있습니다. Annotation은 자바 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종입니다. 소스코드에 추가하면 단순 주석의 기능을 하는 것이 아니라 특별한 기능을 사용할 수 있습니다.

Java에서는 @Override, @Deprecated 와 같은 기본적인 Annotation을 제공합니다. 아래의 상속 예제에서는 @Override 를 이용하여 상속임을 명시해줍니다.

public class Parent { 
    public void doSomething() { 
        System.out.println("This is Parent"); 
    } 
} 

public class Son extends Parent{ 
    @Override 
    public void doSomething() { 
        System.out.println("This is Son"); 
    } 
}

Spring에서는 여러 가지 Annotation을 사용하지만, Bean을 등록하기 위해서는 @Component Annotation을 사용합니다. @Component Annotation이 등록되어 있는 경우에는 Spring이 Annotation을 확인하고 자체적으로 Bean 으로 등록합니다.

@Component: 빈을 선언하는 클래스를 작성하기 위해 넣는 어노테이션이다

실제로 사용되는 예시를 볼까요? 실제 Spring 프로젝트에서 Controller를 등록할 때에는 아래와 같은 Annotation을 사용합니다. 아래의 예시에서 Controller 임을 Spring 에게 알려주기 위하여 @Controller Annotation을 사용했습니다.

// HelloController.java
@Controller
public class HelloController {
// Http Get method 의 /hello 경로로 요청이 들어올 때 처리할 Method를 아래와 같이 @GetMapping Annotation을 사용하여 Mapping을 사용할 수 있습니다.
@GetMapping("hello")
public String hello(Model model){
model.addAttribute("data", "This is data!!");
return "hello";
}
}

@Controller Annotation을 intelliJ에서 Ctrl 을 눌러서 이동해보면 아래와 같은 소스를 확인할 수 있습니다. @Controller Annotation에는 @Component Annotation이 있는 것을 확인할 수 있습니다. @Component Annotation 으로 인하여 Spring은 해당 Controller를 Bean 으로 등록합니다.

// Controller.java

// -- 일부 생략 --
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}

2.2. Bean Configuration File에 직접 Bean 등록하는 방법

@Configuration과 @Bean Annotation 을 이용하여 Bean을 등록할 수 있습니다. 아래의 예제와 같이 @Configuration을 이용하면 Spring Project 에서의 Configuration 역할을 하는 Class를 지정할 수 있습니다. 해당 File 하위에 Bean 으로 등록하고자 하는 Class에 @Bean Annotation을 사용해주면 간단하게 Bean을 등록할 수 있습니다.
@Configuration: 이 어노테이션을 단 클래스는 빈 설정을 담당하는 클래스가 된다.

// Hello.java
@Configuration
public class HelloConfiguration {
    @Bean
    public HelloController sampleController() {
        return new SampleController;
    }
}

어노테이션 (Annotation)

Spring에서 @Component로 다 쓰지 않고 @Repository, @Service, @Controller등을 사용하는 이유는, 예를들어 @Repository는 DAO의 메소드에서 발생할 수 있는 unchecked exception들을 스프링의 DataAccessException으로 처리할 수 있기 때문이다.

@Autowired

속성(field), setter method, constructor(생성자)에서 사용하며 Type에 따라 알아서 Bean을 주입 해준다.
무조건적인 객체에 대한 의존성을 주입시킨다.
이 Annotation을 사용할 시, 스프링이 자동적으로 값을 할당한다.
Controller 클래스에서 DAO나 Service에 관한 객체들을 주입 시킬 때 많이 사용한다.
이 어노테이션은 필드, 메소드, 생성자에다가 넣을 수 있다. 스프링 빈을 가져오는 가장 기본적인 방법.

@Controller

Spring의 Controller를 의미한다. Spring MVC에서 Controller클래스에 쓰인다.

이 어노테이션을 통해 웹 요청의 기준을 담당한다. 이 어노테이션을 통해 빈 등록과 동시에 라우팅 테이블에 등록하는 중요한 어노테이션이다.

@RestController

Spring에서 Controller 중 View로 응답하지 않는, Controller를 의미한다.

method의 반환 결과를 JSON 형태로 반환한다.

이 Annotation이 적혀있는 Controller의 method는 HttpResponse로 바로 응답이 가능하다.
@ResponseBody 역할을 자동적으로 해주는 Annotation이다.
@Controller + @ResponseBody를 사용하면 @ResponseBody를 모든 메소드에서 적용한다.

이 어노테이션을 달면, 모든 컨트롤러 메소드는 @ResponseBody 어노테이션이 달린 반환 값을 달고 다니게 된다. 주로 REST API 설계 시 필수 어노테이션이라 보면 된다.

@Controller 와 @RestController 의 차이

@Controller
API와 view를 동시에 사용하는 경우에 사용한다.
대신 API 서비스로 사용하는 경우는 @ResponseBody를 사용하여 객체를 반환한다.
view(화면) return이 주목적이다.

@RestController
view가 필요없는 API만 지원하는 서비스에서 사용한다.
Spring 4.0.1부터 제공
@RequestMapping 메서드가 기본적으로 @ResponseBody 의미를 가정한다.
data(json, xml 등) return이 주목적이다.

즉, @RestController = @Controller + @ResponseBody 이다.

@Service

Service Class에서 쓰인다.
비즈니스 로직을 수행하는 Class라는 것을 나타내는 용도이다.
이 어노테이션을 단 클래스는. 그저 업무 메소드만 정의하면 된다. 다른 빈에서 가져와 처리를 하고 결과를 제공하는 그저 비즈니스 로직만 정의하면 된다.

@Repository

DAO class에서 쓰인다.
DataBase에 접근하는 method를 가지고 있는 Class에서 쓰인다.

@Configuration

@Configuration을 클래스에 적용하고 @Bean을 해당 Class의 method에 적용하면 @Autowired로 Bean을 부를 수 있다

@RequestMapping

요청 URL을 어떤 method가 처리할지 mapping해주는 Annotation이다.

Controller나 Controller의 method에 적용한다.

요청을 받는 형식인 GET, POST, PATCH, PUT, DELETE 를 정의하기도 한다.

요청 받는 형식을 정의하지 않는다면, 자동적으로 GET으로 설정된다.

@RequestMapping(method = RequestMethod.GET, value = "/path"): 메소드에 달면, 해당 메소드는 이 어노테이션이 설정한 경로를 호출했을 때 메소드가 설정한 응답값을 받게 되며, 컨트롤러 클래스에 달면, 클래스에 설정한 경로를 기준삼아 각 메소드는 클래스 경로의 하위 경로로 추가되어 경로가 잡히게 된다.
또한 method 설정으로 GET만 받거나, POST로 받는 등 특정 HTTP 메소드에만 응답 가능하도록 설정할 수 있다.

@GetMapping

@RequestMapping(Method=RequestMethod.GET)과 같다.
@PostMapping, @PutMapping, @PatchMapping, @DeleteMapping 등 도 있다.

@ResponseBody

HttpMessageConverter를 이용하여 JSON 혹은 xml 로 요청에 응답할수 있게 해주는 Annotation이다.
view가 아닌 JSON 형식의 값을 응답할 때 사용하는 Annotation으로 문자열을 리턴하면 그 값을 http response header가 아닌 response body에 들어간다.

이미 RestController Annotation이 붙어 있다면, 쓸 필요가 없다.
허나 그렇지 않은 단순 컨트롤러라면, HttpResponse로 응답 할 수 있게 해준다.

만약 객체를 return하는 경우 JACKSON 라이브러리에 의해 문자열로 변환되어 전송된다.

context에 설정된 viewResolver를 무시한다고 보면된다.

즉, 컨트롤러 메소드 리턴값에 이 어노테이션을 선언함으로써 스프링은 해당 응답 객체를 클라이언트가 요구하는 요청 내용 유형(Content-Type)에 따라 응답하도록 도와주는 어노테이션이다.

@Getter

Class 내 모든 필드의 Getter method를 자동 생성한다.

@Setter

Class 내 모든 필드의 Setter method를 자동 생성한다.

Controller에서 @RequestBody로 외부에서 데이터를 받는 경우엔 기본생성자 + set method를 통해서만 값이 할당된다.
그래서 이때만 setter를 허용한다.
Entity Class에는 Setter를 설정하면 안된다.
차라리 DTO 클래스를 생성해서 DTO 타입으로 받도록 하자

@RequestParam

(value="name", defaultValue="World"): 컨트롤러 메소드 인자에서 요청값을 받을 때, 요청 주소(URL)에 ? 뒤로 시작하는 질의 문자열, POST 전송 시 요청받을 키/값, 등을 받을 수 있으며, required 속성으로 필수 여부를 지정할 수 있고, defaultValue 속성을 통해 요청이 없을 경우 대체 기본값을 설정할 수 있다. 만약 required = true 일 경우 해당 파라미터 없이 호출하면 400 Bad Request 응답을 뱉도록 스프링에서 설정되어 있다.

@PathVariable

("placeholderName"): 동적 라우팅 구성 시, (예: /path/to/{placeholderName}) 동적 라우팅에 대한 바인딩 값을 가져오는 인자 어노테이션이다. 길게 설명할 거 없이 동적 라우팅에서 동적 값을 가져올 때 없어서 안될 어노테이션이다.

동적 라우팅은 라우팅 테이블에서 경로의 현재 상태에 따라 경로를 자동으로 조정한다.
프로토콜을 사용하여 네트워크 대상과 도달하는 경로를 검색한다.
하나의 경로가 다운되면 네트워크 대상에 도달하도록 자동 조정된다.

구성이 쉽고, 대상 원격 네트워크에 대한 최상의 경로를 선택하고 원격 네트워크를 검색하는 데 더 효과적이다
다만 다른 장비들과 통신하기 위해 더 많은 대역폭을 소비하고, 정적 라우팅보다 안전하지 않다.

참고링크 출처
빈(Bean)이란 ?

어노테이션 정리

어노테이션 정리

profile
코드를 두드리면 문이 열린다

0개의 댓글