신규 Service 개발
Anyframe Core 기반의 Service는 Spring Container 기반 위에 동작하는 서비스로 Spring Bean 작성 방법과 동일하게
생성하면 된다. 여기서는 Anyframe Core의 Technical Service들을 이용하여 사용자 정보를 생성, 수정, 삭제, 조회하는 등의
기능을 제공하는 사용자 관리 서비스를 예로 들어 설명하겠다. 여기서 가이드하는 방법대로 서비스를 생성하는 경우 개발자 간 서비스
작성하는 방식이 표준화되는 장점을 얻을 수 있다. Spring Framework에 대한 자세한 내용은
여기
를 참조하도록 한다.
신규 서비스를 생성하기 위해서는 Dependency Injection 개념을 알고 있어야 한다.
다음은 사용자 관리 서비스 작성 예제이다. 나열된 순서에 따라 서비스를 개발해 보도록 하자.
Dependency Injection
Inversion of Control (IoC)는 component dependency resolution, configuration 과 lifecycle을
해결하기 위한 design pattern이다. IoC의 가장 중요한 부분은 Dependency Resolution 부분이며 사실상 IoC관련
대부분의 문서들이 Dependency Injection 부분을 주로 언급하고있다.
IoC는 다른 용어로도 많이 불리우는데 그중 대표적인 하나가 Robert C. Martin이 그의 Dependency Inversion Principle
논문에서 사용한 DIP라는 용어이고, 다른 하나는 Hollywood Principle (Don't call us we'll call you)이라는
용어이다. IoC에 따라서 디자인된 어떤 서비스는 작업을 수행하기 위해 필요한 다른 서비스들을 직접 생성하거나, 획득하기 보다는
이러한 의존성들이 외부에 정의되고 이 정의에 따라서 컨테이너가 이들 서비스들을 공급해주는 방식으로 동작하게 된다.
주어진 서비스에 대한 의존성이 역전되었다는 이러한 이유로 IoC/DIP/Hollywood Principle 이라는 용어가 사용된다.
IoC는 서비스들이 서로 loosely coupling이 될 수 있도록 도와주며, 이를 통해 다음과 같은 이점을 얻을 수 있다.
- 클래스 / 서비스의 재사용성 증가
- 단위 테스트 용이
- assemble과 configure를 통한 시스템 구축 용이
Dependency Injection에 대해 보다 자세한 설명이 필요한 경우, 본 매뉴얼의 Spring >> IoC >>
Dependencies
를
참고하도록 한다.
Constructor Injection
Constructor Injection은 Dependency Injection 유형의 하나로서, constructor를 통해
객체 자신과 의존 관계가 있는 다른 객체, 서비스, 기타 정보를 얻는 방법을 의미한다.
Source codes
아래의 소스에서는 DepBean을 Constructor를 통해서 제공받겠다고 선언하고있다.
public interface IoCService {
//중략
}
public class IoCServiceImpl implements IoCService
{
public IoCServiceImpl(DepBean dependencyBean) {
this.dependencyBean = dependencyBean;
}
//중략
}
Configuration
IoCServiceImpl에 어떠한 DepBean 서비스의 구현체를 넘겨줄지는 Spring의 경우 서비스 설정
파일인 XML 파일에 정의한다. Constructor를 통한 DI 설정인 경우 <constructor-arg>를 사용하여 다음과
같이 정의한다.
<bean id="IoCService" class="IoCServiceImpl">
<constructor-arg>
<value>DepBean</value>
</constructor-arg>
</bean>
Constructor의 argument 개수가 2개 이상일 경우는 index를 추가하여 다음과 같이 정의할 수 있다.
<bean id="IoCService" class="IoCServiceImpl">
<constructor-arg index="0" ref="beanA" />
<constructor-arg index="1" ref="beanB" />
</bean>
Setter Injection
Setter Injection은 Dependency Injection 유형의 하나로서 setter method를 통해 객체
자신과 의존 관계가 있는 다른 객체, 서비스, 기타 정보를 얻는 방법을 의미한다.
Source codes
아래의 소스에서는 pageSize, pageUnit을 Setter 메소드를 통해서 제공받겠다고 선언하고있다.
public class IoCServiceImpl implements IoCService {
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setPageUnit(int pageUnit) {
this.pageUnit = pageUnit;
}
//중략
}
Configuration
IoCServiceImpl에 어떠한 값을 넘겨줄지는 Spring의 경우 서비스 설정 파일인
XML 파일 설정에 정의한다. setter를 통한 DI 설정인 경우 <property>를 사용하여 다음과 같이 정의한다.
<property> 의 name 속성값에 해당하는 setter 메소드를 호출하여 값이 설정된다.
<bean id="IoCService" >
<property name="pageSize" value="10"/>
<property name="pageUnit" value="10"/>
</bean>
UserService Configuration
설계 산출물인 클래스 다이어그램을 기반으로 신규 서비스인 사용자 관리 서비스를 개발해보도록 하자. 아래의 클래스 다이어그램을
통해 도출된 사용자 관리 서비스의 해당 클래스 명을 기반으로 configuration 파일을 작성한다.
다음은 사용자 관리 서비스를 위한 클래스 다이어그램이다.
applicationContext-user-aop.xml
앞서 제시된 클래스 다이어그램의 참조 관계를 기반으로 Spring 기반의 속성 정의 파일을 생성한다. 다음은
사용자 관리 서비스의 속성을 정의한
applicationContext-user-aop.xml
의
일부이다.
<bean id="UserServiceWithXML" class="com.sds.emp.user.services.impl.UserServiceImplWithXML">
<property name="userDAO">
<bean class="com.sds.emp.user.services.impl.UserDAO">
<property name="queryService" ref="oracle_queryservice" />
<property name="propertiesService" ref="propertiesService" />
</bean>
</property>
</bean>
UserService Source Codes
다음은 사용자 관리 서비스를 구성하는 소스 코드 예제들이다. 앞서 설계한 대로 Service에 대한 Interface, Implementation, DAO, VO 클래스들을
작성하도록 한다.
UserService Interface Class
다음은 인터페이스 클래스의 소스 코드인
UserService.java
의
일부이다.
UserService
public interface UserService {
/** 특정 서비스에 대한 식별자로써 사용하기 위해 ROLE을 정의할 수 있다.
패키지명을 포함한 클래스명을 식별자로 하는 경우 동일한 Bean Id에 대한 사용을 방지할 수 있게 된다.
이러한 경우 특정 Bean을 호출할 때 해당 Bean Id를 직접 문자열로 직접 입력하게 되면 오타로 인해
오류를 발생시킬 수 있으므로, 별도의 static 변수를 정의하여 UserService.ROLE과 같이 사용하는
것도 고려해 볼 수 있다.
*/
String ROLE = UserService.class.getName();
/** 특정 서비스 내에서 동일한 LOGGER를 사용하기 위해 정의할 수 있다. */
Log LOGGER = LogFactory.getLog(UserService.class);
/** 사용자 목록 조회 */
Page getUserList(SearchVO searchVO) throws EmpException;
/** 사용자 정보 조회 */
UserVO getUser(String userId) throws EmpException;
/** 사용자 생성 */
void addUser(UserVO userVO) throws EmpException;
/** 사용자 정보 수정 */
void updateUser(UserVO userVO) throws EmpException;
/** 사용자 아이디 중복 체크 */
boolean checkDuplication(String userId) throws EmpException;
// 중략 ...
}
UserService Implementation Class
다음은 서비스 구현 클래스 소스 코드인
UserServiceImplWithXML.java
의 일부이다. Exception 발생 시 ERROR 레벨의 로그를 남길 때 사용하기 위한 Logging 서비스에 대한 사용법은 매뉴얼의 Tech. Service >>
Logging
을 참고하도록 한다.
UserServiceImplWithXML
public class UserServiceImplWithXML implements UserService, ApplicationContextAware {
private UserDAO userDAO;
private MessageSource messageSource;
/** userDAO setter injection */
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
/** ApplicationContextAware 클래스의 구현 메소드로 특정 서비스의 구현 클래스는
MessageSource Bean을 인식하기 위하여 implements ApplicationContextAware해야 한다*/
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
messageSource
= (MessageSource) applicationContext.getBean("messageSource");
}
/** 사용자 목록 조회 구현 메소드 */
public Page getUserList(SearchVO searchVO) throws EmpException {
// 중략...
}
/** 사용자 정보 조회 구현 메소드 */
public UserVO getUser(String userId) throws EmpException {
// 중략...
}
/** 사용자 생성 구현 메소드 */
public void addUser(UserVO userVO) throws EmpException {
// 중략...
}
/** 사용자 정보 수정 구현 메소드 */
public void updateUser(UserVO userVO) throws EmpException {
// 중략...
}
/** 사용자 아이디 중복 체크 구현 메소드 */
public boolean checkDuplication(String userId) throws EmpException {
// 중략...
}
// 중략...
}
UserService Data Access Object
다음은 DAO 클래스의 소스 코드인
UserDAO.java
의
일부이다.
UserDAO
public class UserDAO {
/** an instance variable for the queryService. */
protected IQueryService queryService;
/** an instance variable for the propertiesService. */
protected IPropertiesService propertiesService;
/** QueryService 사용을 위한 Setter Injection */
public void setQueryService(IQueryService queryService) {
this.queryService = queryService;
}
/** PropertiesService 사용을 위한 Setter Injection */
public void setPropertiesService(IPropertiesService propertiesService) {
this.propertiesService = propertiesService;
}
/** 사용자 목록 조회 */
public Page getUserList(SearchVO searchVO) throws Exception {
// PropertiesService 사용 모습
int pageSize = propertiesService.getInt("PAGE_SIZE");
int pageUnit = propertiesService.getInt("PAGE_UNIT");
// QueryService 사용 모습
HashMap userListMap = queryService
.findWithRowCount("getUserList", iVal, pageIndex, pageSize);
중략...
}
/** 사용자 정보 조회 */
public UserVO getUser(String userId) throws Exception {
// QueryService 사용 모습
Collection userCollection = queryService
.find("getUser", new Object[] { userId });
중략...
}
/** 사용자 생성 */
public void addUser(UserVO userVO) throws Exception {
중략...
// QueryService 사용 모습
queryService.create("addUser", new Object[] { userId, userName
, password, ssn, slYn, birthDay, age, cellPhone, addr, email
, emailYn, imageFile });
}
/** 사용자 정보 수정 */
public void updateUser(UserVO userVO) throws Exception {
중략...
// QueryService 사용 모습
queryService.update("updateUser", new Object[] { userName, ssn, slYn
,birthDay, age, cellPhone, addr, email, emailYn, userId });
}
}
UserService Value Object
다음은 입력/수정을 위한 사용자 정보를 포함한 UserVO 클래스의 소스 코드인
UserVO.java
와
조회를 위한 검색 조건을 포함한 SearchVO 클래스의 소스 코드인
SearchVO.java
의
일부이다. 이때 Value Object는 java.io.Serializable를 implement하도록 하며 멤버 변수는 private으로 선언하고 setter, getter
메소드는 public으로 선언하도록 한다.
UserVO
public class UserVO implements Serializable {
private String userId;
private String userName;
public void setUserId(String param) {
this.userId = param;
}
public String getUserId() {
return this.userId;
}
// 중략...
SearchVO
public class SearchVO implements Serializable {
private String searchCondition = "";
public String getSearchCondition() {
return searchCondition;
}
// 중략...
UserService TestCase
사용자 관리 서비스에서 제공하는 기능(사용자 목록 조회, 사용자 정보 조회, 사용자 생성, 사용자 정보 수정 등)에 대해서
테스트 데이터를 이용하여 제대로 동작하는지 확인해 본다.
UserService 테스트
다음은 사용자 관리 서비스에 대한 테스트 케이스인
UserServiceWithXMLTest.java
의
일부이다.
Resources
다운로드
샘플 테스트 코드를 포함하고 있는 anyframe-usertest-src.zip 파일을 다운받은 후, 테스트 환경 설정
을 참조하여
위에서 제시한 예제 코드를 실행해 볼 수 있다.
| Name |
Download |
| anyframe-usertest-src.zip |
Download
|
참고자료