1. 스프링 프레임워크 소개
* 스프링이란?
– 스프링(Spring)은 간단히 말하면 엔터프라이즈 어플리케이션에서 필요로 하는 기능을 제공
하는 프레임워크이다. 스프링은 J2EE가 제공하는 다수의 기능을 지원하고 있기 때문에,
J2EE를 대체하는 프레임워크로 자리 잡고 있다.
* 스프링 프레임워크 특징
– 스프링은 경량 컨테이너이다. 스프링은 자바 객체를 담고 있는 컨테이너이다. 스프링은 이들
자바 객체의 생성, 소멸과 같은 라이프 사이클을 관리하며, 스프링으로부터 필요한 객체를
가져와 사용 할 수 있다.
– 스프링은 DI(Dependency Injection) 패턴을 지원한다. 스프링은 설정 파일을 통해서 객체 간의
의존 관계를 설정할 수 있도록 하고 있다. 따라서 객체는 직접 의존하고 있는 객체를 생성 하거
나 검색할 필요가 없다.
– 스프링은 AOP(Aspect Oriented Programming)를 지원한다.스프링은 자체적으로 AOP를 지원
하고 있기 때문에 트랜잭션이나 로깅, 보안과 같이 여러 모듈에서 공통으로 필요로 하지만 실제
모듈의 핵심은 아닌 기능들을 분리해서 각 모듈에 적용할 수 있습니다.
– 스프링은 POJO(Plain Old Java Object)를 지원한다. 스프링 컨테이너에 저장되는 자바 객체
는 특정한 인터페이스를 구현하거나 클래스를 상속받지 않아도 된다. 따라서 기존에 작성한
코드를 수정할 필요 없이 스프링에서 사용할 수 있다.
– 트랙젝션 처리를 위한 일관된 방법을 제공한다. JDBC를 사용하든, JTA를 사용하든, 또는 컨테
이너가 제공하는 트랙잭션을 사용하든, 설정 파일을 통해 트랜잭션 관련 정보를 입력 하기
때문에 트랙잭션 구현에 상관없이 동일한 코드를 여러 환경에서 사용 할 수 있다.
– 영속성과 관련된 다양한 API를 지원한다. 스프링은 JDBC를 비롯하여 iBATIS, Hibernate,
JPA, JDO등 데이터베이스 처리와 관련하여 널리 사용되는 라이브러리와의 연동을 지원하고
있다.
– 다양한 API에 대한 연동을 지원한다. 스프링은 JMS, 메일, 스케쥴링 등 엔터프라이즈 어플리
케이션을 개발하는데 필요한 다양한 API를 설정 파일을 통해서 손쉽게 사용할 수 있도록 하고
있다.
* IoC(Inversion of Control)란?
– Spring 프레임워크가 가지는 가장 핵심적인 기능은 IoC(Inversion of Control)이다.자바가
등장한 최초에는 객체 생성 및 의존관계에 대한 모든 제어권이 개발자에 있었다. 그러나,
서블릿, EJB가 등장하면서 제어권이 서블릿과 EJB를 관리하는 서블릿컨테이너 및 EJB 컨테이
너에게 넘어가게 되었다. Spring 프레임워크도 객체에 대한 생성 및 생명주기를 관리할 수
있는 기능을 제공하고 있다. 이와 같은 이유때문에 Spring 프레임워크를 Spring 컨테이너,
IoC컨테이너와 같은 용어로 부르기도 한다.
: 물론 모든 객체에 대한 제어권을 컨테이너에게 넘겨버린 것은 아니다. 서블릿 컨테이너와 EJB
컨테이너에서도 서블릿과 EJB에 대한 제어권만 컨테이너가 담당하고 나머지 객체에 대한 제
어권은 개발자들이 직접 담당하고 있다. 이처럼 Spring 컨테이너 일부 POJO(Plain Old Java
Object)에 대한 제어권을 가진다. Spring컨테이너에서 관리되는 POJO는 각 계층의 인터페이
스를 담당하는 클래스들에 대한 제어권을 가지는 것이 대부분이다.
* Dependency Injection
– DI는 Spring 프레임워크에서 지원하는 IoC의 한 형태이다. DI를 간단히 말하면, 객체 사이의
의존관계를 객체 자신이 아닌 외부의 조립기(assembler)가 수행한다는 개념이다.
일반적인 웹어플리케이션의 경우 클라이언트의 요청을 받아주는 컨트롤러 객체, 비지니스
로직을 수행하는 서비스 객체, 데이터에 접근을 수행하는 DAO객체 등으로 구성된다.
만약, WriteArticleServiceImple클래스가 ArticleDao 인터페이스에 의존하고 있을 경우를 생각
해보자
의존관계를 형성하는 방법에는 아래와 같은 경우들이 있다.
첫번째, 코드에 직접 의존 객체를 명시하는 경우.
public class WriteArticleServiceImpl{
private Article articleDao = new MysqlArticleDao();
….
}
이 경우 의존하는 클래스가 변경되는 경우 코드를 변경해야 하는 문제가 있다.
두번째, Factory 패턴이나 JNDI등을 사용해서 의존 클래스를 검색하는 방법이 있다.
public class WriteArticleServiceImpl{
private ArticleDao articleDao = ArticleDaoFactory.create();
…
}
Factory나 JNDI를 사용하면 첫번째문제(즉, 의존 클래스가 변경되면 코드를 변경해야 하는
문제)를 없앨 수는 있지만, WriteArticleServiceImpl클래스를 테스트하려면 올바르게 동작하는
Factory또는 JNDI에 등록된 객체를 필요로 한다는 문제점이 있다.
세번째, DI패턴이다. 이 방식에서는 의존관계에 있는 객체가 아닌 외부 조립기(assembler)가
각 객체 사이의 의존 관계를 설정해준다.
WriteArticleServiceImpl클래스의 코드는 MysqlArticleDao 객체를 생성하거나 검색하기 위한
코드가 포함되어 있지 않다. 대신 조립기의 역할을 하는 Assembler가 MysqlArticleDao
객체를 생성한 뒤 WriteArticleServiceImpl객체에 전달해 주게 된다.
DI패턴을 적용할 경우 WriteArticleServiceImpl클래스는 의존하는 객체를 전달받기 위한 설정
메서드(setter method)나 생성자를 제공할 뿐 WriteArticleServiceImpl에서 직접 의존하는
클래스를 찾지 않는다.
* AOP(Aspect Oriented Programming)
– 로깅, 트랙잭션처리, 보안과 같은 핵심 로직이 아닌 cross-cutting concern(공통관심사항)을
객체 지향기법(상속이나 패턴등)을 사용해서 여러 모듈에 효과적으로 적용하는데 한계가 있었
으며, 이런 한계를 극복하기 위해 AOP라는 기법이 소개되었다.
공통관심사항(cross-cutting concern)을 별도의 모듈로 구현한 뒤, 각 기능을 필요로 하는 곳
에서 사용하게 될 경우, 각 모듈과 공통 모듈 사이의 의존관계는 복잡한 의존 관계를 맺게 된다.
AOP에서는 각클래스에서 공통 관심사항을 구현한 모듈에 대한 의존 관계를갖기보다는,
Aspect를 이용하여 핵심 로직을 구현한 각 클래스에 공통 기능을 적용하게 된다.
AOP에서는 핵심 로직을 구현한 클래스를 실행하기 전 후에 Aspect를 적용하고, 그 결과로
핵심 로직을 수행하면 그에 앞서 공통 모듈을 실행하거나 또는 로직 수행 이후에 공통 모듈을
수행하는 방식으로 공통 모듈을 적용하게 된다.
AOP에서 중요한 점은 Aspect가 핵심 로직 구현 클래스에 의존하지 않는다는 점이다. AOP에
서는 설정 파일이나 설정클래스 등을 이용하여 Aspect를 여러 클래스에 적용할 수 있도록
하고 있다.
참조 :http://webprogrammer.tistory.com/310