스프링이란 무엇인가?
-. Application Framework
-. 빠르고 효율적으로 사용
-. Application 기본 틀 제공
-. 공통 프로그래밍 모델, 기술API 등을 제공
참고) http://wiki.javajigi.net/pages/viewpage.action?pageId=3664 참고
Spring 프레임워크 구성
Spring Core
Spring 프레임워크의 근간이 되는 IoC(또는 DI) 기능을 지원하는 영역을 담당하고 있다.
BeanFactory를 기반으로 Bean 클래스들을 제어할 수 있는 기능을 지원한다.
Spring Context
Spring Core 바로 위에 있으면서 Spring Core에서 지원하는 기능외에 추가적인 기능들과 좀 더 쉬운 개발이 가능하도록 지원하고 있다.
또한 JNDI, EJB등을 위한 Adaptor들을 포함하고 있다.
Spring DAO
지금까지 우리들이 일반적으로 많이 사용해왔던 JDBC 기반하의 DAO개발을 좀 더 쉽고, 일관된 방법으로 개발하는 것이 가능하도록 지원하고 있다.
Spring DAO를 이용할 경우 지금까지 개발하던 DAO보다 적은 코드와 쉬운 방법으로 DAO를 개발하는 것이 가능하다.
Spring ORM
Object Relation Mapping 프레임워크인 Hibernate, IBatis, JDO와의 결합을 지원하기 위한 기능이다.
Spring ORM을 이용할 경우 Hibernate, IBatis, JDO 프레임워크와 쉽게 통합하는 것이 가능하다.
Spring AOP
Spring 프레임워크에 Aspect Oriented Programming을 지원하는 기능이다. 이 기능은 AOP Alliance 기반하에서 개발되었다.
Spring Web
Web Application 개발에 필요한 Web Application Context와 Multipart Request등의 기능을 지원한다.
또한 Struts, Webwork와 같은 프레임워크의 통합을 지원하는 부분을 담당한다.
Spring Web MVC
Spring 프레임워크에서 독립적으로 Web UI Layer에 Model-View-Controller를 지원하기 위한 기능이다.
지금까지 Struts, Webwork가 담당했던 기능들을 Spring Web MVC를 이용하여 대체하는 것이 가능하다. 또한 Velocity, Excel, PDF와 같은 다양한 UI 기술들을 사용하기 위한 API를 제공하고 있다.
1. Application 기본 틀 - 스프링 컨테이너
-. 스프링 런타임 엔진 제공 : Spring Container 또는 Application Context
-. Spring Container
-. 설정정보를 참고해서 Application을 구성하는 오브젝트를 생성하고 관리
-. 독립적으로 동작할 수도 있지만 보통 웹 모듈에서 동작하는 서비스나 서블릿으로 등록해서 사용
2. 공통 프로그래밍 모델 - IoC/DI, 서비스 추상화, AOP
-. Application을 구성하는 오브젝트가 생성되고 동작하는 방식에 대한 틀을 제공해줄 뿐만 아니라, Application 코드가 어떻게 작성되야 하는 기준 제시 -> 프로그래밍 모델
-. 1. IoC/DI -> 오브젝트의 생명주기와 의존관계에 대한 프로그래밍 모델
참고) http://wiki.javajigi.net/pages/viewpage.action?pageId=3664 참고
IoC
1. IoC(Inversion of Control)이란 무엇인가?
자바가 등장하고 자바 기반으로 애플리케이션을 개발하기 시작하던 최초의 시기에는 자바 객체를 생성하고 객체간의 의존관계를
연결시키는 등의 제어권을 개발자가 직접 가지고 있었다. 그러나 서블릿, EJB가 등장하면서 개발자들의 독점적으로 가지고 있던
제어권이 서블릿과 EJB를 관리하는 컨테이너에게 넘어가 버렸다. 객체에 대한 제어권이 컨테이너에게 넘어가면서 객체의 생명주기를
관리하는 권한 또한 컨테이너들이 전담할 수 밖에 없게 되었다. 이처럼 객체의 생성에서부터 생명주기의 관리까지 모든 객체에 대한
제어권이 바뀐것을 의미하는 것이 제어권의 역전, 즉 Ioc라는 개념이다.
2. Martin Fowler의 Inversion of Control Containers and the Dependency Injection pattern
3. IoC컨테이너의 분류
IoC 개념은 글을 쓰는 저자마다 다양한 방식으로 분류하고 있다. Spring 프레임워크 워크북에 따르면 다음과 같이 분류하고 있다.
3.1. DL(Dependency Lookup) 혹은 DP(Dependency Pull)
Dependency Lookup은 저장소에 저장되어 있는 빈(Bean)에 접근하기 위하여 개발자들이 컨테이너에서 제공하는 API를 이용하여
사용하고자 하는 빈(Bean)을 Lookup하는 것을 말한다. Pro Spring책에서는 Dependency Pull이라고 정의했다.
아래 코드는 JNDI에 저장되어 있는 UserService EJB를 Lookup하는 예제이다.
public class UserServiceDelegate {
protected static final Log logger = LogFactory
.getLog(UserServiceDelegate.class);
private static final Class homeClazz = UserServiceHome.class;
private UserService userService = null;
public UserServiceDelegate() {
ServiceLocator serviceLocator = ServiceLocator.getInstance();
UserServiceHome userServiceHome = (UserServiceHome) serviceLocator
.getRemoteHome(UserServiceHome.JNDI_NAME, homeClazz);
try {
userService = userServiceHome.create();
} catch (RemoteException e) {
..........추가 코드...........
}
}
..........추가 코드...........
}
아래는 Spring 프레임워크 기반하의 UserService 인스턴스를 WebApplicationContext에서 Lookup하고 있다.
public class UserServiceHelper {
private static final String USERSERVICE_BEANID = "userService";
public static UserService getUserService(ServletContext ctx) {
WebApplicationContext wac = WebApplicationContextUtils
.getRequiredWebApplicationContext(ctx);
return (UserService) wac.getBean(USERSERVICE_BEANID);
}
}
3.2 DI(Dependency Injection)
Dependency Injection은 Spring 프레임워크에서 지원하는 IoC의 형태이다.
DI는 클래스 사이의 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동적으로 연결해주는 것을 말한다.
개발자들은 빈 설정 파일(저장소 관리 파일)에 의존관계가 필요하다는 정보를 추가하면 된다.
Spring 프레임워크는 Setter Injection, Constructor Injection, Method Injection의 세가지 유형으로 나타난다
◆ Setter Injection
Setter Injection은 클래스 사이의 의존관계를 연결시키기 위하여 setter 메소드를 이용하는 방법이다. 예제코드는 다음과 같다.
public class UserServiceImpl implements UserService, InitializingBean {
private UserDAO userDAO;
public void setUserDAO(UserDAO newUserDAO) {
this.userDAO = newUserDAO;
}
public int addUser(User user) throws ExistedUserException {
if (userDAO.existedUser(user.getUserId())) {
throw new ExistedUserException(context.getMessage( "user.existed.exception",
new Object[] { user.getUserId() }, null));
}
int result = userDAO.insert(user);
return result;
}
..........추가 코드...........
}
위 코드를 보면 퍼시스턴스 계층과의 통신을 위해 UserDAO 인터페이스와 의존관계가 형성된다.
소스코드 어디에도 UserDAO 구현 클래스의 정보와 인스턴스가 생성되는 곳이 없다.
그러나 위 클래스는 UserDAO 인스턴스가 존재한다는 가정하에 개발을 진행하고 있는데 이것이 가능한 이유는
아래와 같은 Spring 프레임워크의 빈 설정파일에 있다.
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
..........추가 설정...........
<bean id="userDAO" class="net.javajigi.user.dao.MySQLUserDAO">
<bean id="userService" class="net.javajigi.user.service.UserServiceImpl">
<property name="userDAO">
<ref local="userDAO"/>
</property>
</bean>
</beans>
Constructor Injection
Constructor Injection은 생성자를 이용하여 의존관계를 연결시킨다.
위 소스를 Constructor Injection으로 변경하면 다음과 같다.
public class UserServiceImpl implements UserService, InitializingBean {
private UserDAO userDAO;
public UserServiceImpl (UserDAO newUserDAO) {
this.UserDAO = newUserDAO;
}
public int addUser(User user) throws ExistedUserException {
if (userDAO.existedUser(user.getUserId())) {
throw new ExistedUserException(context.getMessage("user.existed.exception",new Object[] { user.getUserId() }, null));
}
int result = userDAO.insert(user);
return result;
}
..........추가 코드...........
}
빈 설정파일은 아래와 같이 작성된다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
..........추가 설정...........
<bean id="userDAO" class="net.javajigi.user.dao.MySQLUserDAO">
<bean id="userService" class="net.javajigi.user.service.UserServiceImpl">
<constructor-arg>
<ref local="userDAO"/>
</constructor-arg>
</bean>
</beans>
-. 2. 서비스 추상화 -> 스프링을 사용하면 환경이나 서버, 특정 기술에 종속되지 않고 이식성이 뛰어나며 유연한 Appliation을 만들 수 있는데, 이를 가능하게 해주는 것
-. 3. AOP -> Application 코드에 산재해서 나타나는 부가적인 기능을 독립적으로 모듈화하는 프로그래밍 모델
3. 기술 API
-. UI 작성은 물론이고 웹프리젠테이션 계층, 비지니스 서비스 계층, 기반 서비스 계층, 도메인 계층, 데이터 액서스 계층 등에서 필요한 주요 기술을 스프링에서 일관된 방식으로 사용할 수 있도록 지원해주는 기능과 전략 클래스 등을 제공
-. 스프링의 모든 기술은 표준 자바 엔터프라이즈 플랫폼(JavaEE)에 기반
스프링의 성공요인
1. 단순함(Simplicity)
-. 스프링이 지향하는 것은 목적을 이룰 수 있는 가장 단순하고 명쾌한 접근방법
-. 자바라는 언어의 근본에서 기존엔터프라이즈 기술의 문제에 대한 해법을 찾음
-. 가장 단순한 객체지향적인 개발모델인 POJO 프로그래밍
2. 유연성(Flexibility)
-. 유연성과 확장성이 매우 뛰어남
-. 스프링은 프레임워크를 위한 프레임워크 또는 여러 프레임워크를 함께 사용하게 해주는 접착(Glue) 프레임워크라 불림
-. "항상 프레임워크 기반의 접근 방법을 사용하라" 의 개발철학을 가진 스프링은 스스로 발전하는 프레임워크임
스프링 학습과활용의 어려움
1. 프레임워크가 지향하는 가치와 프로그래밍 모델을 충분히 이해해야 활용할 수 있음.
2. 스프링의 핵심 가치와 원리에 대한 이해
-. 스프링에는 가장 중요한 핵심가치와 그것이 가능하도록 도와주는 세 가지 핵심 기술과 스프링이 강조하는 중요한 프로그래밍 모델을 이해
3. 스프링의 기술에 대한 지식과 선택 기준 정립
-. 다양한 선택의 문제(스프링과 연동하는 프레임워크는 어떤 것을 선택하고 또 어떤 스타일로 사용할 것인지)를 각 기술영역별로 효과적으로 다루는 법을 배우는 것
-. 스프링이 제공하는 기술의 종류와 접근 방법에는 어떤 것이 있는지 충분히 살펴보고, 선택의 기준을 마련해서 그때그때 상황에 맞는 최선의 기술과 접근 방법을 선택할 수 있어야 함
4. 스프링의 적용과 확장
-. 다양한 기술을 어떻게 실제 Application 개발에 어떤 식으로 적용해야하는지 공부해야함
-. 스프링은 특정 아키택처에 제한된 프레임워크가 아니기에 확장성을 가짐(기술문제로 해결되지 못했던 상황 등)
-. 스프링이 제공한 기능을 사용하는 것 외에도 확장하거나 추상화해서 사용하는 방법을 알아야 함
-. 스프링을 실전에서 사용하는 데 필요한 응용 방법과 확장 방법을 공부하는 것
스프링 3.0의 달라진 기능
1. Java 5와 JavaEE 6
2. 스프링 표현식 언어(SpEL)
-. SpEL은 빈설정에서부터 스프링 MVC의 뷰에 이르기까지 스프링3.0의 다양한 영역에 적용되어 있으며 SpEL API를 Application에서 직접 활용할 수도 있다.
3. 자바 코드를 이용한 DI설정과 DIJ(JSR-330)
-. 기존에 제공되던 XML과 Annotation을 이용한 빈 설정 기능에 자바 코드를 이용한 빈 메탖어보 생성과 DI 설정 기능이 추가됐다.
ex) Java Class or Method -> @Configuration과 @Bean 등의 Annotation을 부여해서 DI 설정정보로 이용
@Inject와 Provider 같은 자바 표준 DI Annotation을 이용한 DI 설정도 지원
4. @MVC와 REST
-. @MVC는 Annotation을 적극적으로 활용해서 웹 프레젠테에션 계층을 편리하게 개발할 수 있도록 만들어진 최신 웹 기술 - 높은 완성도
-. RestTemplate과 Message 컨버터를 이용해 REST 개발을 완벽하게 지원해주기도 함
-. 기타 다수의 다양한 부가 기능 추가
5. 내장형 DB 지원
-. Derby, HSQL, H2에 대한 내장형 DB 지원기능 추가
6. Converter, ConversionService, Formatter
-. 기존에 사용되던 PropertyEditor를 대신할 수 있는 Converter와 ConversionService타입 변환 API가 추가
-. 웹 환경에 특화돼서 만들어진 Formatter도 제공
스프링 3.1에 추가된 새로운 기능
1. 강화된 자바 코드를 이용한 빈 설정
-. 스프링 3.0 부터 지원하기 시작한 자바 코드를 이용한 빈 설정 방식을 대폭 확장
-. XML의 전용 커스텀 태그를 대체할 수 있는, @Enable로 시작하는 전용 Annotation 제공
2. Runtime Environment 추상화
-. 런타임 환경 정보를 추상화한 환경 오브젝트가 컨테이너를 통해 제공
-. 환경 오브젝트가 제공하는 주요 기능
-> 실행환경에 따라 달라지는 빈 설정을 효과적으로 관리 할 수 있는 프로파일과 각종 프로퍼티 정보를 컨테이너를 통해 일관된 방식으로 제공할 수 있게 해주는 프로퍼티소스
3, JPA 지원 확장과 Hibernate 4 지원
4. 새로운 DispatcherServlet 전략과 플래시 맵
-. DispatcherServlet 전략의 일부가 새롭게 설계된 전략으로 대체 -> MVC 기능 확장 편리
-. Post / Redirect / Get 패턴에 사용할 수 있는 플래시 맵 기능 추가
5. 캐시 추상화
-. AOP를 이용한 메소드 레벨의 캐시 추상화 기능이 추가
-. 캐시 구현 기술에 독립적인 방식으로 Application Bean에 캐시 기능을 적용할 수 있음
-. 맵을 이용한 간단한 캐시 구현부터 EhCache를 이용한 고급 캐시 기술까지 지원