|
Space Map
|
Spring 프레임워크 소개와 IoC 및 Spring IoC의 개념 0. 목차
0. 머리말이 문서에서는 Lightweight Container의 선두주자라 할 수 있는 Spring Frmaework에 대한 간단한 소개와 1. Spring Framework 개요1.1 아키텍쳐의 발달과정1.1.1 Non EJB 아키텍쳐![]()
1.1.2 EJB 아키텍쳐![]()
1.1.3 Lightweight Container 아키텍쳐![]()
1.2 Spring 프레임워크 개요
2. IoC2.1 IoC(Inversion of Control)이란 무엇인가?자바가 등장하고 자바 기반으로 애플리케이션을 개발하기 시작하던 최초의 시기에는 자바 객체를 생성하고 객체간의 의존관계를 2.2 Martin Fowler의 Inversion of Control Containers and the Dependency Injection pattern마틴 파울러는 IoC 컨테이너와 Dependency Injection Pattern에 대한 글로써 IoC에 대한 개념을 잘 보여주고 있다. 2.3 IoC컨테이너의 분류IoC 개념은 글을 쓰는 저자마다 다양한 방식으로 분류하고 있다. Spring 프레임워크 워크북에 따르면 다음과 같이 분류하고 있다. ![]() 2.3.1 DL(Dependency Lookup) 혹은 DP(Dependency Pull)Dependency Lookup은 저장소에 저장되어 있는 빈(Bean)에 접근하기 위하여 개발자들이 컨테이너에서 제공하는 API를 이용하여 아래 코드는 JNDI에 저장되어 있는 UserService EJB를 Lookup하는 예제이다. package net.javajigi.user.client; 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하고 있다. package net.javajigi.user.spring; 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); } } 2.3.2 DI(Dependency Injection)Dependency Injection은 Spring 프레임워크에서 지원하는 IoC의 형태이다.
package net.javajigi.user.service; 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 인터페이스와 의존관계가 형성된다. <?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"> <property name="userDAO"> <ref local="userDAO"/> </property> </bean> </beans>
package net.javajigi.user.service; 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>
3. Spring Framework 내의 IoC 개념3.1 Spring Container![]() 3.2 Spring 프레임워크의 초기화
BeanFactory UML Diagram![]() ApplicationContext UML Diagram![]() ApplicationContext의 실제 소스는 다음과 같다. package org.springframework.context; import org.springframework.beans.factory.HierarchicalBeanFactory; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.core.io.support.ResourcePatternResolver; /** * Central interface to provide configuration for an application. * This is read-only while the application is running, but may be * reloaded if the implementation supports this. * * <p>An ApplicationContext provides: * <ul> * <li>Bean factory methods, inherited from ListableBeanFactory. * This avoids the need for applications to use singletons. * <li>The ability to resolve messages, supporting internationalization. * Inherited from the MessageSource interface. * <li>The ability to load file resources in a generic fashion. * Inherited from the ResourceLoader interface. * <li>The ability to publish events. Implementations must provide a means * of registering event listeners. * <li>Inheritance from a parent context. Definitions in a descendant context * will always take priority. This means, for example, that a single parent * context can be used by an entire web application, while each servlet has * its own child context that is independent of that of any other servlet. * </ul> * * <p>In addition to standard bean factory lifecycle capabilities, * ApplicationContext implementations need to detect ApplicationContextAware * beans and invoke the setApplicationContext method accordingly. * * @author Rod Johnson * @author Juergen Hoeller * @see ApplicationContextAware#setApplicationContext */ public interface ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver { ApplicationContext getParent(); String getDisplayName(); long getStartupDate(); void publishEvent(ApplicationEvent event); } 소스의 중간에 javadoc를 위한 주석을 보면 ApplicationContext는 BeanFactory가 가지고 있는 기능 외에 추가적인 기능을 지원하고 있다는 것을 알 수 있다. 애플리케이션을 개발할 때에는 거의 모든 경우에 ApplicationContext를 사용하면 된다. package net.javajigi.user.dao; ..........추가 코드........... public class MySQLUserDAOTest extends TestCase { private ApplicationContext ctx; private UserDAO userDAO; protected void setUp() throws Exception { String[] paths = { "/WEB-INF/applicationContext.xml" }; ctx = new ClassPathXmlApplicationContext(paths); userDAO = (UserDAO) ctx.getBean("userDAO"); } ..........추가 코드........... } 3.3 Spring 프레임워크에서 빈의 생명주기 관리![]()
package net.javajigi.user.service; ..........추가 코드........... public class UserServiceImpl implements UserService, InitializingBean { protected final Log logger = LogFactory.getLog(getClass()); private UserDAO userDAO; private ExceptionMailSender mailSender; public void afterPropertiesSet() throws Exception { if (userDAO == null) { throw new Exception(context.getMessage("instance.not.init", new Object[] { "UserDAO" }, null)); } if (mailSender == null) { throw new Exception(context.getMessage("instance.not.init", new Object[] { "ExceptionMailSender" }, null)); } } public void setUserDAO(UserDAO newUserDAO) { this.userDAO = newUserDAO; } public void setMailSender(ExceptionMailSender mailSender) { this.mailSender = mailSender; } ..........추가 코드........... }
package net.javajigi.user.service; ..........추가 코드........... public class UserServiceImpl implements UserService { protected final Log logger = LogFactory.getLog(getClass()); private UserDAO userDAO; private ExceptionMailSender mailSender; public void init() throws Exception { if (userDAO == null) { throw new Exception(context.getMessage("instance.not.init", new Object[] { "UserDAO" }, null)); } if (mailSender == null) { throw new Exception(context.getMessage("instance.not.init", new Object[] { "ExceptionMailSender" }, null)); } } public void setUserDAO(UserDAO newUserDAO) { this.userDAO = newUserDAO; } public void setMailSender(ExceptionMailSender mailSender) { this.mailSender = mailSender; } ..........추가 코드........... } <beans> ..........추가 설정........... <bean id="userService" class="net.javajigi.user.service.UserServiceImpl" init-method="init"> <property name="userDAO"> <ref local="userDAO"/> </property> <property name="mailSender"> <ref local="mailSender"/> </property> </bean> ..........추가 설정........... </beans>
Non Singleton 방식으로 관리하고자 한다면 빈 속성중에 "singleton" 속성을 false로 설정하면 된다. Singleton과 Non-Singleton을 설정하기 위한 예제 를 참고하도록 하자. 4. 토론꺼리
5. 맺음말
이 문서는 지속적으로 업데이트를 계속할 예정이고 앞으로는 예제중심의 문서를 계속해서 추가해나가고자 한다. 참고문헌
문서에 대하여최초작성자 : 강현수
|
|









Comments (8)
4월 04, 2006
남연숙 says:
현수오빠 화이팅^^ 좋은 세미나 기대할게요현수오빠 화이팅^^ 좋은 세미나 기대할게요
4월 04, 2006
박재성 says:
형 근무시간에 일 안하고 문서작업 하셔도 되요..? 근무시간에는 열심히 일해야지..ㅋㅋ 좋은 문서와 세미나 기대하고 있겠습니다.형 근무시간에 일 안하고 문서작업 하셔도 되요..?
근무시간에는 열심히 일해야지..ㅋㅋ
좋은 문서와 세미나 기대하고 있겠습니다.
4월 04, 2006
안용상 says:
형..열심이시네요. 은근히 기대되는걸요.. 수고하세요.형..열심이시네요.
은근히 기대되는걸요.. 수고하세요.
4월 06, 2006
김형준 says:
Spring은 저도 기대가 많이 됩니다. 좋은 내용 부탁드립니다. 홧팅Spring은 저도 기대가 많이 됩니다.
좋은 내용 부탁드립니다. 홧팅
4월 06, 2006
강현수 says:
아!! 점점 더 부담이 된다..ㅡ.ㅡ;;아!! 점점 더 부담이 된다..ㅡ.ㅡ;;
4월 06, 2006
고덕성 says:
음.. 부담을 좀 더 줘보자.. 내일 통통!! 튀는 Spring의 실체를 파악해 볼 수 있는 훌륭한 세미나가 되겠지......^^ 고생이 많네...음.. 부담을 좀 더 줘보자..
내일 통통!! 튀는 Spring의 실체를 파악해 볼 수 있는 훌륭한 세미나가 되겠지......^^
고생이 많네...ㅎㅎ
4월 07, 2006
박재성 says:
앗..제가 어제 토론꺼리 3개 올렸는데 날라갔다.. 어디로 간걸까.?앗..제가 어제 토론꺼리 3개 올렸는데 날라갔다..
어디로 간걸까.?
4월 07, 2006
장회수 says:
오늘 못갈것 같은데.. 토론에 대한 의견들이 여기에 올라왔으면 하는 간곡한 바램이 있습니다.~~~~ ^^오늘 못갈것 같은데.. 토론에 대한 의견들이 여기에 올라왔으면 하는 간곡한 바램이 있습니다.~~~~ ^^