본문 바로가기

Web/spring

[Spring Error] Servlet.service() for servlet

728x90

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

 

구글링해보니 이 오류가 나타나는 이유 몇가지가 있었다

 

1. 쿼리값 주입 여부 체크
2. DB run 체크
3. 인스턴스 변수(필드 변수) 의존성 주입

 

읽어보고 코드를 보니

 

하..............

하ㅏ하

 

 

 

정말 간단한 휴먼 오류였다ㅜㅠ

 

private Service -> private final Service 로 바꾸니 바로 해결

 

아무래도.. 아직 final 에 대한 정확한 이해도가 떨어지는 상태라

제대로 써야할 곳에 쓰지못해서가 아닌가 싶었다

 

그래서 final 에 대해서 좀더 확인해보고 포스팅 끝내기로-!

 

 

final 은 오직 한번만 할당하겠다는 entity 를 정의할 때 쓴다

final로 선언된 변수가 할당되면 같은 값을 가지고 객체 상태가 바뀌어도 매번 동일한 내용을 참조한다

재할당할 수 없도록 만드는 것이다<<<

 

라고 한다.

 

 

 

 

이런 식으로, 작성한다.

@Service
public class AService {
  private final ARepository aRepository;

  // @AllArgsConstructor 어노테이션 사용하면 같은 효과
  public AService(ARepository aRepository) {
    this.aRepository = aRepository;
  }
}

 

저 this.~ 는 생성자 주입(Constructor Injection = CI) 이라고 스프링에서 필드주입보다 스프링에서 권장하는 방법이라고 한다.

앱 쓸 때 워낙 저 방식을 많이 써서 그런가 (그놈의 context 엄청 끌고 다녔찌...) 저게 더 익숙하다

 

각 컴포넌트간의 의존성이 생겼을 때 빈을 주입하는 순서가 주입방법 마다 다르다고 한다.

 

저 생성자주입 방식을 사용하면 객체를 생성하는 시점이 주입하게 된다. (먼저 생성 안한다는 뜻!!)

 

순환참조를 방지하고, 테스트 코드를 작성할 수 있고, final 을 사용하여 immutable 하게 관리할 수 있다.

 

 

 

 

728x90