## 의존성주입
하나의 객체가 다른 객체 없이 역할을 제대로 행할 수 없다는 것 = 의존성
A객체가 B객체 없이 동작이 불가능한 상황을 A가 B에 의존적이다 라고 표현한다.
의존성 주입이란, 어떤 객체가 필요한 객체를 외부에서 밀어 넣는다. 라는 것
스프링에서는 생성자를 이용한 주입, Setter 메소드를 이용한 주입으로 의존성 주입을 구현한다.
설정방식은 XML이나 어노테이션을 이용해 처리한다.
pom.xml
<!-- Spring TEST -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<scope>provided</scope>
</dependency>
<!-- log4j -->
1.2.17버전으로 변경한다.
<!-- Test -->
4.12버전으로 변경한다
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
ex00프로젝트에 sample패키지 생성하고 Restaurant, Chef클래스 생성.
package org.zerock.sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import lombok.Data;
import lombok.Setter;
@Component
@Data
public class Restaurant {
@Setter(onMethod = @__({@Autowired}))
private Chef chef;
}
package org.zerock.sample;
import org.springframework.stereotype.Component;
import lombok.Data;
@Component
@Data
public class Chef {
}
Restaurant객체는 Chef타입의 객체를 필요로 한다.
@Component는 스프링에게 해당 클래스가 스프링에서 관리해야하는 대상임을 표현
@Setter는 자동으로 set~()를 컴파일 시 생성함
스프링은 클래스에서 객체생성, 객체들의 의존성 처리작업까지 내부에서 처리됨
root-context.xml(bean을 설정하는 설정파일)
위 파일클릭 후 nameSpaces탭에서 context 체크 후 source 추가
<!-- Root Context: defines shared resources visible to all other web components -->
<context:component-scan base-package="org.zerock.sample">
</context:component-scan>
해당 작업 완료후 하단의 bean graph 탭에 Restaurant, Chef객체가 설정된 것 을 확인할 수 있다.
java 설정에서는 root-context 대신하는 RootConfig클래스.
@ComponentScan 어노테이션을 이용해, 기존 xml에서 설정된 내용을 처리할 수 있다.
@Configuration
@ComponentScan(basePackages = {"org.zerock.sample"})
public class RootConfig {
}
스프링이 시작되면, 스프링이 사용하는 메모리 영역을 만들게 된다.
이 메모리 영역은 컨텍스트라고 한다. , 스프링에서는 ApplicationContext라는 객체가 생성된다.
그렇다면 스프링이 객체를 생성 및 관리해야하는 객체들의 설정이 필요한데, 이 설정은 root-context에서 할 수 있다.
root-context에 설정되어 있는 context-scan 태그를 통해, "패키지명"을 스캔하기 시작한다.
해당 패키지에 있는 클래스 중에서 @Component라는 어노테이션이 존재하는 클래스의 인스턴스를 생성한다.
Restaurant객체는 Chef객체가 필요하다는 어노테이션설정이 있으므로, 스프링은 chef객체의 레퍼런스를 Restaurant 객체에 주입한다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class SampleTest {
@Setter(onMethod_ = {@Autowired})
private Restaurant restaurant;
@Test
public void testExist() {
assertNotNull(restaurant);
log.info(restaurant);
log.info("------------------");
log.info(restaurant.getChef());
}
}
@RunWith - > 테스트코드가 스프링을 실행하는 역할을 할 것
@ContextConfiguration 지정된 클래스 또는 문자열을 이용해 객체를 스프링 내의 객체로 등록.(빈 등록)
@Log4j 로그를 기록함
assertNotNull(변수) 해당 변수가 NULL이 아니어아먄 테스트가 성공.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RootConfig.class})
@Log4j
public class SampleTests{
...
}