purplely88's home

시작에 앞서

7장을 완료해주세요.

 

DI 라이프 사이클 관리 기능에 앞서

DI안에서는 인스턴스를 생성하고 그것을 변수에 넣는다는 것은 이제 충분히 이해하셨을 거라 봅니다.

하지만 DI 기능은 이거뿐만이 아닙니다.

 

DI에서는 라이프 사이클 관리도 행해지고 있습니다.

WEB 애플리케이션 개발하는 상에서는 꽤나 편리한 기능입니다만, 함정이 있습니다. (헉)

그럼 알아보도록 하겠습니다.

 

DI 라이프 사이클 관리

애초에 라이프 사이클 관리라는 것이 무엇이 나면, 인스턴스 생성과 파괴를 관리해주는 것입니다.

 

인스턴스를 생성할 때에 통상은 new를 붙여서 생성합니다. 반대로 인스턴스의 파괴는 변수에 null를 넣습니다.

사용하지 않게 된 변수에 null을 넣지 않으면, 메모리상에 그대로 남게 되어 낭비가 되기 때문입니다.

이것은 퍼포먼스에 영향을 준다는 지, 메모리 부족에서부터 시스템 정지까지도 일어날 수 있습니다.

 

그렇지만 @Autowired를 붙인 필드에 null을 일부러 넣을 필요는 없습니다.

스프링이 자동으로 해주기 때문에! 오홍

 

또한, Java에 Web 애플리케이션을 작성할 때에는 서블릿을 사용합니다.

서블릿을 사용할 때는 인스턴스를 Session 스코프나 Request 스코프에 등록합니다만, 이것도 스프링에서 해줍니다.

 

하지만, 그 인스턴스가 언제 파괴되는지에 대한 것을 꼭 파악해 둘 필요는 있습니다.

 

스코프

Session 스코프나 Request 스코프라고 하는 것은 인스턴스에 유효기간을 말합니다.

Java의 로컬변수를 상상해보세요. if문안에 선언한 변수는 if 안이 스코프이기 때문에, if문 밖에서는 사용할 수 없습니다.

 

각 스코프의 유효기간은 아래와 같습니다.

 

Session 스코프

유저가 로그인할때부터 로그아웃하기까지의 유효기간입니다.

예를들어, 유저 정보나 그것과 연관된 권한과 같은 정보를 Session 스코프로 가지고 있습니다.

 

Request 스코프

HTTP의 요청(Request)이 유효기간입니다.

예를 들어, 유저가 등록 화면에 각 항목을 입력한 후, 등록 버튼을 누르면, 입력 값을 출력되는 결과 화면이 표시됩니다. 

그 경우에 유저 등록 화면부터 결과 화면까지가 Request 스코프의 범위가 됩니다.

 

그러면 어떻게 해서 라이프 사이클 관리를 하는지는 @Scope 어노테이션을 붙입니다.

그리고 그 어노테이션에 어떤 스코프를 등록할지를 지정합니다. 

예를 들어, 아래와 같이 씁니다.

 

@Scope 샘플

 

@Component

@Scope("prototype")

public class SampleComponent {

 

}

 

빨간 글씨의 prototype은 Bean을 취득할 때마다 매회 새로운 인스턴스가 생겨나는 의미입니다.

※ prototype 외에도 singleton, session, sequest 등등 여러 가지가 있으니 검색!

 

@Component 외에도 @Bean이나 @Controller에서도 @Scope 어노테이션을 이용할 수 있습니다.

@Scope 어노테이션을 이용함으로써, 간단히 인스턴스 생성과 파괴가 가능해졌습니다.

 

DI 함정 첫 번째 - singleton

여기서부터는 스프링의 DI에 자주 있는 함정에 대해서 설명해보도록 하겠습니다.

먼저, singleton을 썼을 경우에 함정입니다.

 

스프링을 갓 배우기 시작하면, @Scope를 붙이는 것을 모른 채로 어노테이션을 만드는 경우가 있습니다.

특히 인터넷상에서는 간단하게 사용하는 방법을 배웠을 경우도 포함입니다.

 

@Scope를 붙이지 않으면, 인스턴스가 singleton에 작성됩니다.

singleton이란, Java의 디자인 패턴 중 한 가지입니다.

singleton이면 오브젝트의 인스턴스는 하나밖에 만들 수 없습니다.

 

singleton이 원인이 되어 버그가 발생되는 경우는 적습니다만, 아무리 조사해도 원인을 알지 못할 때에는

singleton이니까 발생한 것이 아닌가? 하는 의구심도 가질 필요가 있습니다.

 

※ @Controller, @Service, @Repository의 스코프는 통상 singleton으로 충분합니다.

 

DI 함정 두 번째 - 스코프의 차이

함정 두 번째는 스코프의 차이입니다.

예를 들어, singleton 스코프의 인스턴스가 prototype 스코프의 오브젝트를 가지고 있을 경우입니다.

 

prototype 스코프 샘플

@Component

@Scope("prototype")

public class PrototypeComponent {

 

}

 

singleton 스코프 샘플

@Component

public class SingletonComponent {

  @Autowired

  private PrototypeComponent component;

}

 

이렇게 함으로써 prototype 스코프를 설정한 Bean (PrototypeComponent)이 singleton스코프로 되어버립니다.

다른 예로는 request 스코프를 설정한 Bean을 session 스코프의 Bean에서 가질 때 위와 같은 상황이 되어버립니다.

 

스코프가 다른 Bean을 필드로써 가지는 경우는 주의가 필요합니다.

 

마무리

DI?

DI는 한 단어로 말해서 인스턴스 관리를 하는 것을 뜻한다.

인스턴스 관리는 인스턴스의 생성과 스코프 관리를 말한다.

@Controller와 같은 어노테이션이 붙은 클래스의 인스턴스를 DI 컨테이너에 등록한다.

DI컨테이너에 등록된 클래스를 Bean이라고 말한다.

@Autowired를 사용하면 DI 컨테이너로부터 getter로 인스턴스를 취득할 수 있다.

 

DI 실행 방법

1. 어노테이션 베이스

2. JavaConfig

3. xml

4. JavaConfig + 어노테이션 베이스

5. xml + 어노테이션 베이스

(주로 4번과 5번을 많이 사용한다.)

 

라이프 사이클 관리

DI에서는 인스턴스 스코프를 설정할 수 있다.

스코프는 @Scope 어노테이션에서 설정할 수 있다.

디폴트 값으로는 singleton으로 되며, 인스턴스가 하나밖에 생성되지 않는다.

스코프가 다른 인스턴스를 필드에서 가질 경우에는 주의가 필요하다.

'프로그래밍 > 스프링 부트' 카테고리의 다른 글

10. 데이터 바인딩 & 밸리데이션 (2/4)  (0) 2020.06.23
9. 데이터 바인딩 & 밸리데이션 (1/4)  (0) 2020.06.20
7. DI (3/4)  (0) 2020.06.16
6. DI (2/4)  (0) 2020.06.16
5. DI (1/4)  (0) 2020.06.14