스프링이란?
IOC와 AOP를 지원하는 경량의 컨테이너 프레임워크.
IOC 제어의 역행(Inversion of Control)
애플리케이션 구성 객체 간의 느슨한 결합, 즉 낮은 결합도를 유지.
IOC 적용 전에는 앱 수행에 필요한 객체의 생성이나 객체간 의존관계를 개발자가 직접 자바 코드로 처리했다. 이런 상황에서 의존관계에 있는 객체를 변경하면 반드시 자바 코드를 수정해야 한다.
IOC가 적용되면 객체 생성을 자바 코드가 아니라 컨테이너가 대신 처리한다. 객체 간 의존관계도 컨테이너가 처리한다. 즉 소스에 의존관계가 명시되지 않으므로 결합도가 떨어져 유지보수가 편리해진다.
관점지향 프로그래밍(Aspect Oriented Programming)
공통으로 사용하는 기능들을 외부의 독립된 클래스로 분리하고, 해당 기능을 코드에 직접 명시하지 않고 선언적으로 처리하여 적용한다. 응집도가 높은 비즈니스 컴포넌트를 만들어 유지보수를 향상시킨다.
컨테이너(Container)
특정 객체의 생성과 관리를 담당하며 객체 운용에 필요한 다양한 기능을 제공한다.
컨테이너는 일반적으로 서버 안에 포함되어 배포 및 구동된다. 대표적으로 Servlet객체를 생성하고 관리하는 Servlet컨테이너와 EJB객체를 생성하고 관리하는 EJB컨테이너가 있다. 스프링도 일종의 컨테이너다.
지금부터는 결합도가 높은 프로그램의 코드를 살펴보고, 결합도를 낮추기 위한 방법인 다형성과 디자인 패턴을 이용한 코드, 그리고 마지막으로 IOC를 적용한 코드를 살펴볼 것이다.
SamsungTV 클래스
LgTV 클래스
TVUser 클래스
삼성과 엘지는 같은 기능을 하는 메소드의 이름이 다르다. 유저 클래스에서 한번에 하나씩 클래스를 가져와 실행한다. 삼성티비를 시청할 때는 삼성티비 생성자로 객체를 생성하고 메소드를 호출한다. 두 티비가 메소드 시그니처(메소드의 이름과 매개변수 이름)가 다르므로 티비를 바꾸면 코드 대부분을 수정해야 한다.
다형성을 이용하려면 상속, 메소드 재정의(오버라이딩Overriding), 형변환이 필요하다.
TV클래스들이 최상위 부모로 사용할 TV인터페이스를 만들고 모든 티비가 공통으로 가져야 할 메소드들을 추상 메소드로 선언한다. (powerOn, powerOff)
삼성티비와 엘지티비가 implements TV 하도록 수정해주고 powerOn()과 powerOff()를 오버라이딩한다.
TVUser클래스의 메인에서는 TV 인터페이스 타입의 변수로 삼성 또는 엘지 티비 객체를 참조하도록 한다. 즉, 묵시적 형변환(Promotion)을 이용한다.
package polymorphism;
public class TVUser {
public static void main(String[] args) {
TV tv = new LgTV();
tv.powerOn();
tv.powerOff();
}
}
다형성을 이용해도 여전히 TV클래스 객체를 생성하는 소스를 수정해야 한다.
클라이언트 소스를 수정하지 않고 TV를 교체할 수 있다면 편리할 것이다.
Factory팩토리 패턴은 클라이언트에서 사용할 객체 생성을 캡슐화해 TVUser와 TV사이를 느슨한 결합 상태로 만들어준다.
package polymorphism;
public class BeanFactory {
public Object getBean(String beanName) {
if(beanName.equals("samsung")) {
return new SamsungTV();
}else if(beanName.equals("lg")) {
return new LgTV();
}
return null;
}
}
빈팩토리 클래스에는 팩토리 패턴이 적용되어 있다.
package polymorphism;
public class TVUser {
public static void main(String[] args) {
BeanFactory factory = new BeanFactory();
TV tv = (TV)factory.getBean(args[0]);
tv.powerOn();
tv.powerOff();
}
}
명령행 매개변수로 "lg"나 "samsung"을 넣어주면 getBean이 그에 맞는 삼성티비 또는 엘지티비 객체를 리턴한다.