백엔드(스프링)
DI(Dependency Injection)에 대한 설명과 해당 기술의 장점에 대해 설명
스프링에서 의존성 주입(DI)란,
객체간 의존성을 개발자가 객체 내부에서 직접 호출(new 연산자)하는 대신, 외부(스프링 컨테이너)에서 객체를 생성해서 넣어주는 방식.
외부에서 두 객체 간의 관계 설정을 해주는 디자인 패턴,
인터페이스를 사이에 두어 클래스 레벨에서는 의존관계가 고정되지 않도록 하고,
런타임 시 관계를 동적으로 주입하여 유연성을 확보하고 결합도를 낮출 수 있게함
DI를 사용 시 장점?
public class Controller {
private Service service;
service.test();
}
}
다음과 같이 Controller 객체가 Service 객체를 사용하고 있는 경우, Controller는 Service에 의존성이 있다고 할 수있다.
의존한다는 것 -> 의존 대상, 여기서는 Service가 변하면 그것이 Controller에게로 전달된다는 뜻.
만약, Servcie의 test()메소드가 변경되면 Controller에서도 그에 따른 수정이 필요하게 되거나 형식은 그대로지만 로직이 변경되면 결과적으로 Controller의 기능에도 영향을 미친다.
이와같이 두 객체간의 관계를 맺어주는 것을 의존성 주입이라고 하며,
스프링에는 3가지 방법의 의존성 주입방법이 있다.
@Controller
public class Controller{
private Service service;
@Autowired
public Controller(Service service){
this.service = service;
}
}
생성자에 @Autowired를 붙여 의존성을 주입받을 수 있다.
클래스 내 생성자가 하나이고, 그 생성자로 주입받을 객체가 빈으로 등록되어 있다면 @Autowired 생략 가능하다.
생성자 주입은 인스턴스 생성시 1회 호출되는 것이 보장되기 때문에, 주입받은 객체가 변하지 않거나, 반드시 객체주입이 필요한 경우 강제하기 위해 사용된다.
@Controller
public class Controller{
@Autowired
private Service service;
}
코드가 간결하고 편하지만 의존 관계를 정확히 파악하기 힘들다.
필드 주입시 final 키워드를 선언할 수 없어 객체가 변할 수 있다.
주입이 동시에 일어나 겹치는 경우 순환참조 에러가 난다.
@Controller
public class Controller{
private Service service;
@Autowired
public setService(Service service){
this.service = service;
}
}
setter 혹은 사용자정의 메서드를 통해 의존관계 주입.
setter의 경우 객체가 변경될 필요성이 있을 때만 사용된다.(주입하는 객체를 변경하는 경우는 드물다.)
스프링에서는 생성자 주입을 권장
인텔리제이에서 필드주입 사용시 경고창 뜸.
Spring 프레임워크는 3가지 핵심 프로그래밍 모델 지원.
그 중 하나 -> DI
DI?
외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴,
인터페이스를 사이에 둬서 클래스 레벨에서는 의존관계까 고정되지 않도록 하고 런타임 시에 관계를 동적으로 주입하여 유연성을 확보하고 결합도를 낮출 수 있게 해줌.
public class Store {
private Pencil pencil;
public Store() {
this.pencil = new Pencil();
}
}
연필이라는 상품과 1개의 연필을 판매하는 Store 클래스가 있다고 치면,
위와 같은 예시 클래스는 다음과 같은 문제점을 가진다.
결국 위와 같은 문제점이 발생하는 근본적인 이유는 Store에서 불필요하게 어떤 제품을 판매할지에 대한 관심이 분리되지 않았기 때문.
Spring에서는 DI를 적용해 이러한 문제를 해결.
Spring MVC에서의 예외 처리 기법에 대해서 설명
스프링의 처리과정을 보면 예외가 발생하는 부분은 크게 두가지.
예외(Exception)처리는 어떻게?
스프링의 MVC 에러 중 99프로는 DispatcherServlet에서 발생.
DispatcherServlet 내에서 발생하는 예외를 내부에서 자체적으로 해결할 수 있음.
-> HandlerExceptionResolver를 사용한 예외 전략
컨트롤러 작업 중 발생한 예외를 어떻게 결정할 지 결정하는 전략
Spring MVC에서의 예외 처리는 애플리케이션에서 발생하는 예외를 적절하게 처리하고, 사용자에게 적절한 응답을 제공하는 기법입니다. Spring MVC는 다양한 방법을 제공하여 예외 처리를 수행할 수 있습니다.
컨트롤러 클래스 내부에 @ExceptionHandler 어노테이션을 사용하여 특정 예외를 처리하는 메소드를 정의할 수 있습니다.
이 메소드는 예외가 발생했을 때 해당 예외를 처리하는 역할을 수행합니다.
예외 처리 메소드는 컨트롤러 내에서 예외가 발생하면 실행되며, 예외에 대한 적절한 응답을 반환할 수 있습니다.
@ControllerAdvice 어노테이션을 사용하여 전역 예외 처리 클래스를 정의할 수 있습니다.
이 클래스는 여러 컨트롤러에서 발생하는 예외를 처리하는 역할을 수행합니다.
@ExceptionHandler 어노테이션과 함께 사용하여 특정 예외에 대한 처리를 수행할 수 있습니다.
또한, @InitBinder 및 @ModelAttribute 어노테이션을 사용하여 컨트롤러에 대한 전역 설정을 수행할 수도 있습니다.
ResponseEntity를 사용하여 예외 발생 시 HTTP 응답 상태 코드와 함께 사용자에게 적절한 응답을 제공할 수 있습니다.
예를 들어, ResponseEntity의 status 메소드를 사용하여 응답 상태 코드를 설정하고, body 메소드를 사용하여 응답 본문을 설정할 수 있습니다.
@ExceptionHandler 메소드는 예외를 처리하는 기본적인 기능 외에도 다양한 기능을 수행할 수 있습니다.
예를 들어, 특정 예외에 대한 로깅, 예외 정보를 기반으로한 통계 수집, 예외 발생 시 이메일 알림 등의 작업을 수행할 수 있습니다.