OOP : 객체 지향 프로그래밍(Object-Oriented Programming)
객체 간의 관계를 구성할 때 별도의 API 등을 사용하지 않는 Plain Old Java Object의 구성만으로 가능하다. → 이는 개발자가 특정 라이브러리나 컨테이너의 기술에 종속적이지 않다는 것을 의미.
왜 외부에서 객체를 주입하는 방식을 사용하는가? - 주입받는 입장에서 어떤 객체인지 신경 쓸 필요가 없다, 어떤 객체에 의존하든 자신의 역할은 변하지 않는다.
스프링에서는 ApplicationContext 가 필요한 객체들을 생성하고 주입한다. 이렇게 관리되는 객체들을 빈Bean이라고 부르고, 빈과 빈 사이의 의존관계를 xml설정, 어노테이션 설정, 자바 설정 방식 등을 사용해 설정할 수 있다.
AOP : Aspected Oriented Programming
횡단 관심사(cross-concern)를 모듈로 분리하는 프로그래밍 패러다임.
AspectJ의 문법을 통해 작성한다.
하나의 업무가 여러 작업으로 이루어지는 경우의 트랜잭션 처리. 어노테이션이나 xml로 설정할 수 있어 매번 코드를 작성할 필요가 없다.
레스토랑 객체를 만들고 레스토랑에서 일하는 셰프 객체를 주입하는 예제.
스프링에서는 의존성 주입을
으로 구현한다. 설정방식은 주로 xml이나 어노테이션으로 처리한다.
수정하거나 추가할 부분. (롬복은 이미 01에서 추가함)
주의: log4j 1.2.15에 exclusion이 여러 개 달려있는 전체 태그를 그냥 다 주석처리하고 dependency를 새로 적는다. exclusion 놔두면 오류남.
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
junit 라이브러리를 4.12버전으로 변경했는지 확인한다.
Chef.java
package org.zerock.sample;
import org.springframework.stereotype.Component;
import lombok.Data;
@Component
@Data
public class Chef {
}
Restaurant.java
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;
}
<context:component-scan base-package="org.zerock.sample"></context:component-scan>
스프링이 시작되면 ApplicationContext 객체가 만들어진다. 이 객체가 관리하는 빈들의 설정이 root-context.xml 파일이다. 이 파일에 설정해놓은 <context:component-scan> 태그에 따라 해당 패키지를 스캔하기 시작한다. 패키지의 클래스들 중 @Component 어노테이션이 존재하는 클래스의 인스턴스를 생성한다. @Autowired(의존성 필요하다는 설정)에 따라 스프링은 Chef객체의 레퍼런스를 Restaurant 객체에 주입한다.
테스트 작업은 프로젝트 초기에 설정해 두고 사용하는 것이 좋다.
Run As > Junit Test로 결과 확인

호텔에서도 Chef가 필요하다고 생각하고 SampleHotel 클래스를 작성해보자.
@Autowired 어노테이션 대신 생성자를 선언하고 Chef를 주입한다.
SampleHotel.java
package org.zerock.sample;
import org.springframework.stereotype.Component;
import lombok.Getter;
import lombok.ToString;
@Component
@ToString
@Getter
public class SampleHotel {
private Chef chef;
public SampleHotel(Chef chef) {
this.chef = chef;
}
}
HotelTests.java
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 HotelTests {
@Setter(onMethod_ = { @Autowired })
private SampleHotel hotel;
@Test
public void testExist() {
assertNotNull(hotel);
log.info(hotel);
log.info("------------------------------");
log.info(hotel.getChef());
}
}