[spring] 스프링이 동작하면서 생기는 일

업데이트:


스프링이 동작하면서 생기는 일

  • 스프링 프레임워크가 시작되면 먼저 스프링이 사용하는 메모리 영역을 만들게 되는데 이를 컨텍스트(context)라고 한다. 스프링에서는 ApplicationContext라는 이름의 객체가 생성된다.
  • 스프링은 자신이 객체를 생성하고 관리해야 하는 객체들에 대한 설정이 필요한데, 이에 대한 설정이 root-context.xml 파일이다.
  • root-context.xml에 설정되어 있는 <context:component-scan> 태그의 내용을 통해서 ‘org.zerock.sample’ 패키지를 스캔한다.
  • 해당 패키지에 있는 클래스들 중에서 스프링이 사용하는 @Component라는 어노테이션이 존재하는 클래스의 인스턴스를 생성한다.
  • Restaurant 객체는 Chef 객체가 필요하다는 어노테이션 @Autowired 설정이 있으므로, 스프링은 Chef 객체의 레퍼런스를 Restaurant 객체에 주입한다.






테스트 코드를 통한 확인

프로젝트 내 ‘src/test/java’ 폴더 내에 ‘org.zerock.sample.SampleTests’ 클래스를 추가한다.

테스트1

package org.zerock.sample;

import static org.junit.Assert.assertNotNull;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import lombok.Setter;
import lombok.extern.log4j.Log4j;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class SampleTests {
	
	@Setter(onMethod_ = {@Autowired})
	private Restaurant restaurant;
	
	@Test
	public void testExist() {
		assertNotNull(restaurant);
		
		log.info(restaurant);
		log.info("--------------------");
		log.info(restaurant.getChef());
	}
}


테스트 코드는 우선 현재 테스트 코드가 스프링을 실행하는 역할을 할 것이라는 것을 @Runwith 어노테이션으로 표시한다.
그 다음으로 가장 중요한 설정은 @ContextConfiguration 어노테이션과 속성값인 문자열 설정이다.

  • @RunWith : 테스트 코드가 스프링을 실행하는 역할을 할 것이라는 걸 표시함
  • @ContextConfiguration : 지정된 클래스나 문자열을 이용해서 필요한 객체들을 스프링 내에 객체로 등록한다. 이 어노테이션에 사용하는 문자열은 ‘classpath:’나 ‘file:’을 이용할 수 있다.
  • @Log4j : Lombok을 이용해서 로그를 기록하는 Logger를 변수로 생성한다. Logger 객체의 선언 없이도 Log4j 라이브러리와 설정이 존재한다면 바로 사용할 수 있다. ‘Spring Legacy Project’는 별도의 설정이 필요 없다. 로그에 대한 설정은 ‘src/main/resources’와 ‘src/test/resources’에 별도로 존재한다.
  • @Autowired : 해당 인스턴스 변수가 스프링으로부터 자동으로 주입해 달라는 표시이고, 스프링은 정상적으로 주입이 가능하다면 obj 변수에 Restaurant 타입의 객체를 주입하게 된다.
  • @Test : JUnit에서 테스트 대상을 표시하는 어노테이션이다.
  • assertNotNull() : restaurant 변수가 null이 아니어야만 테스트가 성공한다는 것을 의미한다. 테스트 작업은 초기에 설정해주도 사용하는 습관을 가지는 것이 좋다.


Run As > Junit Test를 실행해서 테스트 결과를 확인한다.


테스트2


실행된 결과에서 주목해야하는 부분은 다음과 같다.

  • new Restaurant()와 같이 Restaurant 클래스에서 객체를 생성한 적이 없지만 객체가 만들어졌다는 점 : 스프링은 관리가 필요한 객체(Bean)를 어노테이션 등을 이용해서 객체를 생성하고 관리하는 일종의 컨테이너팩토리 기능을 가지고 있다.
  • @Data 어노테이션으로 Lombok을 이용해서 여러 메서드가 만들어진다는 점 : Lombok은 자동으로 getter/setter 등을 만들어 주는데 스프링은 생성자 주입 혹은 setter 주입을 이용해서 동작한다. Lombok을 통해서 getter/setter 등을 자동으로 생성하고 onMethod 속성을 이용하여 작성된 setter에 @Autowired 어노테이션을 추가한다.
  • Restaurant 객체의 Chef 인스턴스 변수(멤버 변수)에 Chef 타입의 객체가 주입되어 있다는 점 : 스프링은 @Autowired와 같은 어노테이션을 이용해서 개발자가 직접 객체들과의 관계를 관리하지 않고, 자동으로 관리되록 한다.






코드에 사용된 어노테이션들

Lombok 관련 어노테이션 Spring 관련 어노테이션 테스트 관련 어노테이션
@Setter @Autowired @RunWith
@Data @Component @ContextConfiguration
@Log4j   @Test


Lombok 관련

@Setter 어노테이션은 setter 메서드를 만들어주는 역할을 한다. Restaurant 클래스를 조사해 보면 아래와 같이 @Setter 메서드가 작성된 것을 확인할 수 있다.

테스트3

@Setter에는 세 가지 속성을 부여해줄 수 있다.

  • value
    • 접근 제한 속성을 의미한다.
    • 기본값은 lombok.AccessLevel.PUBLIC
  • onMethod
    • stter 메서드의 생성 시 메서드에 추가할 어노테이션을 지정한다.
  • onParam
    • setter 메서드의 파라미터에 어노테이션을 사용하는 경우에 적용한다.



@Data는 Lombok에서 가장 자주 사용되는 어노테이션이다. @ToString(), @EqualsAndHashCode, @Getter/@Setter, @RequiredArgsConstructor를 모두 결합한 형태로 한 번에 자주 사용되는 모든 메서드들을 생성할 수 있는 장점이 있다.



Spring 관련

@Component는 해당 클래스가 스프링에서 객체로 만들어서 관리되는 대상임을 명시하는 어노테이션이다. @ComponentScan을 통해 지정되어 있으므로 해당 패키지에 있는 클래스들을 조사하면서 @Component가 존재하는 클래스들을 객체로 생성해 빈(Bean)으로 관리한다.

@Autowired는 스프링 내부에서 자신이 특정한 객체에 의존적이므로 자신에게 해당 타입의 빈을 주입하라는 표시이다. 스프링은 @Autowired 어노테이션을 보고 스프링 내부에 관리되는 객체들 중 적당한 것이 있는지 확인하고, 자동으로 주입해준다.

테스트 관련 어노테이션

@ContextConfiguration은 스프링이 실행되면서 어떤 설정 정보를 읽어 들여야 하는지를 명시한다. 속성으로는 locations를 이용해서 문자열의 배열로 XML 설정 파일을 명시할 수도 있고, classes 속성으로 @Configuration이 적용된 클래스를 지정해 줄 수도 있다.

@RunWith는 테스트 시 필요한 클래스를 지정한다. 스프링은 SpringJUint4ClassRunner 클래스가 대상이 된다. @Test는 junit에서 해당 메서드가 jUnit 상에서 단위 테스트의 대상인지 알려준다.





  • 참고 : 코드로 배우는 스프링 웹 프로젝트

태그:

카테고리:

업데이트:

댓글남기기