Spring프레임워크가 시작되면 먼저 스프링이 사용하는 메모리의 영역을 만든다.
이 영역을 Context라고 하고, Spring에서는 ApplicationContext라는 메모리 객체가 생성된다.
Spring은 자신이 객체를 생성하고 관리해야 하는 객체들에 대한 설정이 필요하다.
==> 이에 대한 설정은 root-context.xml파일이 해준다.
2.5 root-context.xml에 설정되어 있는 <context:component-scan> 태그의 내용을 통해서
'com.xml.ex'패키지를 스캔한다.(com.xml.ex 같은 경우는 내 프로젝트 패키지 경로이다.)
<context:component-scan base-package="com.xml.ex">
</context:component-scan>
스캔하는 패키지에 있는 클래스들 중에서 스프링이 사용하는
@Component어노테이션이 존재하는 클래스의 객체를 생성한다.
@Component : 스프링에게 해당 클래스가 스프링에서 관리해야 하는 대상임을 표시한다.
Restaurant객체는 Chef객체가 필요하다는 @Autowired어노테이션이 설정되어 있다.
-> 스프링은 Chef객체의 레퍼런스를 Restaurant 객체에 주입한다.
@Autowired : 자신이 특정한 객체에 의존적이므로 자신에게 해당 타입의 빈을 주입해달라는 표시
예제에서는 Restaurant객체에 @Autowired가 설정되어 있다.
=> 스프링은 @Autowired 어노테이션을 보고 스프링 내부에 관리되는 객체들 중 적당한 것이 있는지 확인하고, 자동으로 주입해준다.
Restaurant Setter주입
@Component
@Data
public class Restaurant{
@Setter(onMethod_=@Autowired)
private Chef chef;
Restaurant 생성자 주입
@Component
@Data
public class Restaurant{
private Chef chef;
public Restaurant(Chef chef){
this.chef=chef;
}
@Data : Data어노테이션 같은 경우는 Lombok 이라는 라이브러리의 어노테이션이고,
getter/setter, toString(), 생성자 등을 자동으로 생성해준다.
밑에 사진을 참고하면 좋을 것 같다.
@Data어노테이션을 지운다면 toString() , getChef(), setChef()등이 없어지는 것을 확인할 수 있다.
@Runwith
테스트 시 필요한 클래스를 지정하며, 스프링의 경우에는 SpringJunit4ClassRunner 클래스가 대상이 된다.
@ContextConfiguration
스프링이 실행되면서 어떤 설정 정보를 읽어들여야 하는지를 명시한다.
지정된 클래스나 문자열을 이용해서 필요한 객체들을 스프링 내에 객체(Bean)으로 등록하게 된다.
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring~~/root-context.xml")
이렇게 어노테이션을 적어주고, root-context.xml 파일에 있는com.xml.ex 패키지를 실행해준다. <context:component-scan base-package="com.xml.ex"></context:component-scan>
@Test
Junit에서 테스트 대상을 표시하는 어노테이션이다.
해당 메소드를 선택하고 JUnit Test 기능을 실행하게 한다.
이제 Test코드를 작성해보자. 경로는 그림과 같다.
Test코드는 다음과 같이 작성해준다.
assrtNotNull(restaurant)는 restaurant가 null이 아니면 테스트가 성공하는 것을 의미한다.
Test코드가 성공하면 console에 나오는 로그에 대한 설명
Test코드가 실행되기 위해서 스프링 프레임워크가 동작한다.
: new Restaurant()와 같이 Restaurant클래스에서 객체를 생성한 적 없는데 객체가 만들어짐
=> 스프링은 관리가 필요한 객체(Bean)을 어노테이션 등을 이용해서 객체를 생성하고 관리한다.
동작하는 과정에서 필요한 객체들이 스프링에 등록되었다.
: Restaurant 클래스의 @Data 어노테이션으로 Lombok을 이용해서 여러 메서드가 만들어짐
getter/setter, toString() 등이 자동 생성된다.
의존성 주입이 필요한 객체는 자동으로 주입이 이루어짐
: Restaurant 객체의 Chef 인스턴스 변수에 Chef 타입의 객체가 주입되어 있다.
스프링은 @Autowired와 같은 어노테이션을 이용해서 개발자가 직접 객체들과의 관계를 관리하지 않고, 자동으로 관리한다.
: 스프링4.3 이후 단일 생성자의 묵시적 자동 주입
흔히 보는 Setter방식과 달리 생성자를 선언하고, Chef를 주입하도록 작성되었다.
@Component
@ToString
@Getter
public class Hotel{
private Chef chef;
public Hotel(Chef chef){
this.chef=chef;
}
}
자 여기서 더 간결하게 만들어보자.
@Component
@ToString
@Getter
@AllArgsConstructor
public class Hotel{
private Chef chef;
}
@AllArgsConstructor : 인스턴스 변수로 선언된 모든 것을 파라미터로 받는 생성자를 작성하게 된다.
==> 변수로 선언된 것이 Chef타입이기 때문에 생성자로 Chef를 받도록 만들어 진 것을 확인할 수 있다.
여러 개의 인스턴스 변수들 중에서 특정 변수로만 생성자를 작성하고 싶은 경우에는
@RequiredArgsConstructor와 @NonNull어노테이션을 이용한다
@Component
@ToString
@Getter
@RequiredArgsConstructor
public class Hotel{
@NonNull
private Chef chef;
private Res res;
}
이렇게 만들 경우 @NonNull어노테이션이 붙은 Chef의 생성자만 만들어낸다.
출처 : 코드로 배우는 스프링 웹 프로젝트