프레임워크설계및구축 Spring.NET 어플리케이션 프레임워크 어플리케이션프레임워크란단어는자바개발자들에겐지겨울정도로자주듣는말이겠지만, 닷넷개발자들에겐그리익숙한단어가아니었다. 그만큼어플리케이션프레임워크가가져다주는편리함을누리지못함은물론이고각프레임워크들이내재하고있는디자인패턴

Similar documents
쉽게 풀어쓴 C 프로그래밊

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

Spring Boot/JDBC JdbcTemplate/CRUD 예제

Spring Boot

PowerPoint Presentation

Microsoft PowerPoint - CSharp-10-예외처리

gnu-lee-oop-kor-lec06-3-chap7

C++ Programming

JAVA PROGRAMMING 실습 08.다형성

* Factory class for query and DML clause creation * tiwe * */ public class JPAQueryFactory implements JPQLQueryFactory private f

JAVA PROGRAMMING 실습 05. 객체의 활용

PowerPoint Presentation

- JPA를사용하는경우의스프링설정파일에다음을기술한다. <bean id="entitymanagerfactory" class="org.springframework.orm.jpa.localentitymanagerfactorybean" p:persistenceunitname=

Design Issues

Web Services 와 EAI

Spring Data JPA Many To Many 양방향 관계 예제

(Microsoft PowerPoint - java1-lecture11.ppt [\310\243\310\257 \270\360\265\345])

Network Programming

Microsoft PowerPoint - 04-UDP Programming.ppt

Cluster management software

PowerPoint Presentation

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

제11장 프로세스와 쓰레드

PowerPoint Presentation

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

JUNIT 실습및발표

MVVM 패턴의 이해

PowerPoint Presentation

PowerPoint Presentation

예제 2) Test.java class A intvar= 10; void method() class B extends A intvar= 20; 1"); void method() 2"); void method1() public class Test 3"); args) A

슬라이드 1

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp");

PowerPoint Presentation

JAVA PROGRAMMING 실습 09. 예외처리

C# Programming Guide - Types

iii. Design Tab 을 Click 하여 WindowBuilder 가자동으로생성한 GUI 프로그래밍환경을확인한다.

[Brochure] KOR_TunA

윈도우시스템프로그래밍

PowerPoint 프레젠테이션

1. 자바프로그램기초 및개발환경 2 장 & 3 장. 자바개발도구 충남대학교 컴퓨터공학과

게시판 스팸 실시간 차단 시스템

Microsoft PowerPoint - hci2-lecture12 [호환 모드]

Microsoft PowerPoint - Supplement-03-TCP Programming.ppt [호환 모드]

Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 11 년 10 월 26 일수요일

오버라이딩 (Overriding)

슬라이드 1

Microsoft PowerPoint 장강의노트.ppt

PowerPoint Presentation

ISP and CodeVisionAVR C Compiler.hwp

유니티 변수-함수.key

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

(Microsoft PowerPoint - hci2-lecture12 [\310\243\310\257 \270\360\265\345])

Microsoft PowerPoint - 03-TCP Programming.ppt

OOP 소개

쉽게 풀어쓴 C 프로그래밍

Connection 8 22 UniSQLConnection / / 9 3 UniSQL OID SET

쉽게 풀어쓴 C 프로그래밍

쉽게 풀어쓴 C 프로그래밍

PowerPoint 프레젠테이션

Microsoft PowerPoint - Lect04.pptx

PowerPoint 프레젠테이션

슬라이드 제목 없음

Microsoft PowerPoint - 2강

1. 객체의생성과대입 int 형변수 : 선언과동시에초기화하는방법 (C++) int a = 3; int a(3); // 기본타입역시클래스와같이처리가능 객체의생성 ( 복습 ) class CPoint private : int x, y; public : CPoint(int a

DocsPin_Korean.pages

rmi_박준용_final.PDF

ALTIBASE 사용자가이드 Templete

교육자료

Interstage5 SOAP서비스 설정 가이드

(8) getpi() 함수는정적함수이므로 main() 에서호출할수있다. (9) class Circle private double radius; static final double PI= ; // PI 이름으로 로초기화된정적상수 public

TTA Journal No.157_서체변경.indd

어댑터뷰

한국 컴퓨터그래픽스(디지털컨텐츠)의 현황과 미래 위기인가? 기회인가?

API - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

제목

Java Agent Plugin Guide

17장 클래스와 메소드

FileMaker 15 ODBC 및 JDBC 설명서

Microsoft PowerPoint - chap01-C언어개요.pptx

<4D F736F F F696E74202D2036C0CFC2B05FB0B4C3BCC1F6C7E2C7C1B7CEB1D7B7A1B9D62E707074>

PowerPoint Template

예외 예외정의예외발생예외처리예외전파 단정 단정의선언 단정조건검사옵션 2

작성자 : 김성박\(삼성 SDS 멀티캠퍼스 전임강사\)

PowerPoint Presentation

표준프레임워크로 구성된 컨텐츠를 솔루션에 적용하는 것에 문제가 없는지 확인

본 강의에 들어가기 전

JAVA PROGRAMMING 실습 02. 표준 입출력

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

설계란 무엇인가?

PowerPoint 프레젠테이션

Cloud Friendly System Architecture

Semantic Consistency in Information Exchange

Microsoft Word - src.doc

<4D F736F F F696E74202D20B5A5C0CCC5CDBAA3C0CCBDBA5F3130C1D6C2F75F32C2F7BDC32E >

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

Microsoft PowerPoint - GUI _DB연동.ppt [호환 모드]


JDBC 소개및설치 Database Laboratory

DBMS & SQL Server Installation Database Laboratory

Transcription:

프레임워크설계및구축 Spring.NET 어플리케이션 프레임워크 어플리케이션프레임워크란단어는자바개발자들에겐지겨울정도로자주듣는말이겠지만, 닷넷개발자들에겐그리익숙한단어가아니었다. 그만큼어플리케이션프레임워크가가져다주는편리함을누리지못함은물론이고각프레임워크들이내재하고있는디자인패턴, 아키텍처등에대한건전한토론과논쟁조차도활발하지못했으며이는곧닷넷기반에서개발된어플리케이션에대한불신과선입견을준것또한사실이다. 다행히최근국내와국외를막론하고닷넷환경에서도어플리케이션프레임워크도입과관련한활발한의견이개진되고있으며, 특히오픈소스어플리케이션프레임워크를실제어플리케이션에적용한사례도하나둘씩늘어나고있다. 스텝 3 바이스텝 연재순서 1 회 2009. 1 애플리케이션과프레임워크동시개발 2 회 2009. 2 프레임워크엔지니어링 1 3 회 2009. 3 프레임워크엔지니어링 2 4 회 2009. 4 Spring.NET 어플리케이션프레임워크 5 회 2009. 5 ibatis.net 연재가이드운영체제 윈도우 2K/XP 사용도구 VS2005, Spring.NET 1.2.0 기초지식 C# 응용분야 엔터프라이즈프로그래밍 권효중 fog_rain@naver.com http://fun nygangstar.tistory.com ( 주 ) 중외정보기술솔루션개발팀에근무하고있으며, 닷넷환경에서도어플리케이션프레임워크, 오픈소스가널리사용되길바라는평범한개발자이다. 필자는어플리케이션프레임워크중오픈소스기반의 Spring.NET과데이터베이스접근기술인 ibatis.net에대해서 2회에걸쳐연재하려고한다. Spring.NET을한마디로설명한다면닷넷환경에서사용할수있는 IoC(Inversion of Control) 기반의어플리케이션프레임워크라고할수있다. Spring 프레임워크는자바개발환경에서이미널리사용되고있는프레임워크이며 Spring.NET은이의닷넷버전이다. 그렇다고는하나 Spring.NET은자바버전의프레임워크와는많은부분에서다른기능을제공하고있다. 물론 IoC, AOP 등의핵심기술과사상은동일하다. 덧붙여이글을읽게될독자분들께바램이있다면 Spring. NET이근원적으로지향하는부분은단지어플리케이션프레임워크로써다양한기능을제공하는데있는것이아니라특정모듈로부터상속받지않은순수닷넷객체 (PONO) 를활용하여어플리케이션전체의유연성을극대화하고자하는것이므로 Spring.NET의세세한기능에만너무몰입하지않기를바란다. Spring.NET에서제공하는주요기능은다음과같다. - Dependency Injection / Inversion of Control - Aspect Oriented Programming - Data Access 지원 : ADO.NET, NHibernate 래퍼제공및편리한트랜잭션지원 - ASP.NET WebForm 지원 : ASP.NET 페이지에대한 DI, 양방향데이터바인딩, 유효성검증기능등 - 분산기술지원 : PONO 기반 Remoting, Web Service, Enterprise Service 지원이외에도 Job Scheduling 라이브러리인 Quartz.NET, 메시지전달기술인 Apache ActiveMQ, MSMQ와의연동모듈을제공하고있다. 여기에서는이중에서도가장많이사용되는기능인 DI, AOP, Database Access, 분산기술지원 ( 일명 Spring Services) 에대해서알아보도록하겠다. Dependency Injection Spring.NET의가장핵심은 Sring.Core 어셈블리에서제공하는 DI 기능이다. Spring.NET이제공하는나머지기능들도모두 DI 또는후에설명할 AOP에기반한기능들이라고볼수있다. 물론, DI 기능자체를개발자의어플리케이션에서사용하는것또한가능하다. 262 m a s o

Spring.NET 애플리케이션프레임워크 이번기고에서는 Dependency Injection이무엇이며그와관련된쟁점이나필요성, 장단점을다루는것이목적이아니므로이에대해궁금한독자들은아래의페이지를참조하길바란다. - 위키피디아의 DI 페이지 : http://en.wikipedia.org/wiki/dependency_injection - 마틴파울러블로그의 DI 기사 : http://martinfowler.com/articles/injection.html Spring.NET에서는 Spring.Core 어셈블리를통해서 DI 기능을제공하고있으며, IObjectFactory 인터페이스가객체의생성과소멸등을관리하는최상위인터페이스이며, 개발자는 IObjectFactory를구현한 IApplicationContext를통해 DI 기능을사용하게된다. Spring.NET은 XML을사용한선언적방식, 또는프로그래밍방식을통해서 DI 기능을사용할수있도록하고있으며주로 XML을사용하는것이일반적이고, 윈폼어플리케이션의경우 App.Config, 웹어플리케이션의경우엔 Web.Config 파일을사용할수있다. Spring.NET에서객체를실제코드에주입하는방법은프로퍼티를사용하는방식과생성자의인자값에주입하는방식, 두가지가있다. 어떤방법이더유용한지에대해서는많은논쟁들이있으며, 어떤방법이더나을것인지는개발환경에따라다를수있을것이다. 참고로 Spring.NET 개발팀에서는생성자를사용하는방법이너무비대한생성자를만들어낼수있다는이유로프로퍼티를이용한주입방식을옹호하고있지만, 상황에따라유연하게사용할것을권장하고있다. 프로퍼티를사용하여객체를주입하는방법은 < 리스트 1> 에서처럼설정파일에사용할객체를선언하고 < 리스트 2> 와같이코드에서는프로퍼티에선언한객체의인스턴스가마치생성된것처럼사용하면된다. < 리스트 1> DI 설정 XML 파일 <object id="serviceobject" type="serviceapp.serviceobject, ServiceApp"> <property id="dao" ref="daoobject"/> <object id="daoobject" type="daoapp.daoobject, DaoApp"> < 리스트 2> 주입받은인스턴스를사용하는코드 public class ServiceObject : IService { private IDAO dao; // XML 파일에서설정한객체의인스턴스가 Dao 프로퍼티에 // 주입된다. public IDAO Dao { get { return dao; set { dao = value; public void AddUser(int id, string name) { // 프로퍼티에주입된인스턴스를사용하여로직구현 Dao.InsertUser(id, name); 어플리케이션개발시 DI 기능이쓰일만한곳은어떤상황일까? 기본적으로어플리케이션전체를아우르는객체의생성과소멸을관장하는역할을할수있을것이다. 코드에서는인터페이스에기반한계약된메소드를활용하고실제사용될객체는 XML 파일에서선언적으로지정함으로써흔히들객체지향프로그래밍방식의최종목표처럼예를드는레고조립이나자동차부품조립하듯모듈간의 Dependency를최대한줄여주어궁극적으로소프트웨어의진정한모듈화를가져올수있을것이다. 구체적으로는다음과같은상황도충분히 DI 기능을고려해볼만할것이다. - 어플리케이션이지원해야할데이터베이스의종류가다양한경우 - 특정시점에실행시켜야할모듈이많거나변경이잦은경우 첫번째의경우에대해서설명하자면, 데이터베이스접근코드를사용하는클라이언트레이어또는서비스레이어의코드변경없이 DI 설정파일의변경만으로데이터베이스를유연하게변경해가며사용할수있도록하는것이다. 물론, ORM 프레임워크를사용하는경우엔예외가될수있을것이지만, 데이터베이스종류별로다르게지원되는특화된기능들을여전히사용하고픈개발자들에겐매력적인기능일것이다. 두번째상황은 < 리스트 3> 을참조하자. < 리스트 3> 의코드는개발자들이코딩할때흔히만들어낼수있는코드중하나다. < 리스트 3> 폼시작시초기화작업을수행하는코드샘플 public class Form { public Form() { NetworkCheck(); GetUserAuthority(); SetUI(); SetGrid(); m a s o 263

스텝바이스텝 3 어떠한어플리케이션이시작되거나폼이구동될때초기화를위해여러가지체크를하는경우가많을것이고, 더상황이안좋은경우는이러한체크가더늘어나거나자주변경되는경우가있을것이다. 이러한경우도 DI 기능을이용하면훨씬유연하고우아한코드를만들어낼수있다. 구체적으로설명하자면, 우선초기화메소드들을클래스로뽑아내고공통의인터페이스를구현하게한후 DI 설정파일에서초기화에사용될객체들을선언하고사용할폼이나어플리케이션시작모듈에주입해주면추후에초기화모듈이더해지거나수정되더라도코드는변경할필요없이설정파일의변경만으로원하는효과를만들어낼수있다. < 리스트 4> 와 < 리스트 5> 의코드는이러한동작을수행할코드의주요부분이다. 먼저초기화작업을시행할객체들을 DI 방식으로생성하고 Form 클래스생성자의인자값에주입한다. < 리스트 4> 초기화작업을수행할객체들을 DI 방식을사용하여선언하고주입한다. <object id="networkcheck" type="myapp.networkcheck, MyApp" /> <object id="getuserauthority" type=" MyApp.GetUserAuthority, MyApp" /> <object id="setui" type="myapp.setui, MyApp" /> <object id="setgrid" type=" MyApp.SetGrid, MyApp" /> <object id="form" type="myapp.form, MyApp"> <constructor-arg name="startmodules"> <list> <ref object=vnetworkcheck" /> <ref object="getuserauthority" /> <ref object="setui" /> <ref object="setgrid" /> </list> </constructor-arg> 이후 < 리스트 5> 의코드에서처럼생성자를통해주입된객체를컬렉션에서꺼내어실행시킨다. < 리스트 5> DI 를사용한초기화작업진행 public class Form : IForm { public Form(){ public Form(IList startmodules) { // 생성자의인자로전달받은컬렉션에서인스턴스들을꺼내어 // 각각의모듈들을실행시킨다. foreach (IStartModule module in startmodules) { module.execute(); // 개별모듈들이구현할인터페이스 public interface IStartModule { void Execute(); public class NetworkCheck : IStartModule { Console.WriteLine("NetworkCheck Class Excuted"); public class GetUserAuthority : IStartModule { Console.WriteLine("GetUserAuthority Class Excuted"); public class SetUI : IStartModule { Console.WriteLine("SetUI Class Excuted"); public class SetGrid : IStartModule { Console.WriteLine("SetGrid Class Excuted"); Aspect Oriented Programming 이번엔 Spring.NET의또하나의핵심기능인 AOP 기능에대해서알아보도록하자. AOP의개념에대해서는인터넷을통해수많은글들을볼수있으니, 여기서는 Spring.NET에서제공하는 AOP 지원기능에대해서만보도록하겠다. Spring.NET은아래의 4가지인터페이스를통해서메소드의실행전, 실행후, 실행전후, 예외발생시에개발자가필요한기능을실행시킬수있다. - IAfterReturningAdvice - IMethodInterceptor - IMethodBeforeAdvice - IThrowsAdvice < 리스트 6>,< 리스트 7>,< 리스트 8> 의코드는 IMethodInter ceptor 인터페이스를구현하여메소드의실행시간을추출하는간단한샘플이다. 264 m a s o

Spring.NET 애플리케이션프레임워크 < 리스트 6> 수행시간을측정할메소드를사용하는코드 class Program { static void Main(string[] args) { IApplicationContext ctx = ContextRegistry.GetContext(); ICommand command = (ICommand)ctx["MyCommand"]; command.targetmethod(); public interface ICommand { void TargetMethod(); public class MyCommandObject : ICommand { public void TargetMethod() { for (int i = 0; i < 100; i++) { Thread.Sleep(10); Console.WriteLine(" 실행완료 "); < 리스트 7> Around Advice // IMethodInterceptor 인터페이스를구현하여타겟메소드의실행전과후를캡쳐한다. public class RunningTimdAroundAdvice : IMethodInterceptor { public object Invoke(IMethodInvocation invocation) { Stopwatch stopwatch = new Stopwatch(); stopwatch.start(); object returnvalue = invocation.proceed(); stopwatch.stop(); Console.WriteLine(string.Format("{0 메소드의실행시간은 {1 입니다.", invocation.method.name, stopwatch.elapsed.totalmilliseconds.tostring())); <property name="interceptornames"> <list> <value>aroundadvice</value> </list> </property> AOP는주로어플리케이션에서로깅, 인증등의처리에서자주사용되며, 이후에보게될 Spring.NET 트랜잭션기능도 AOP를사용하여처리하고있다. 주로어플리케이션의코드에서핵심비즈니스로직외에중복사용되는코드들을줄이고자할때매우효율적일것이다. 이렇게실제비즈니스로직외에코드의작동에필요한주변코드들 ( 로깅, 인증, 트랜잭션처리등 ) 이줄어들게되면코드는좀더명확하게어떤의도를가지고있는지보여지게될것이다. 수작업으로처리하던주변코드들 (AOP에서는이를 Cross Concern, 횡단관심사라고부름 ) 은비즈니스로직코드파일이아닌 XML 등의설정파일에선언되어 AOP 컨테이너에의해실제필요한부분에주입되게된다. 이점이바로 AOP가 OOP 의대체개념이아닌 OOP를더욱 OOP답게하는개념이라는것이다. 진정한객체지향적프로그래밍으로보이기위해어쩌면 AOP 개념은반드시필요하다고할수있다. Data Access 다음으로 Spring.NET에서제공하는데이터액세스및트랜잭션기능에대해서보도록하겠다. 이미기존에나와있는데이터액세스프레임워크나라이브러리들이많음에도불구하고 Spring.NET에서별도로데이터액세스모듈을지원하는것은주로아래의기능들을제공하기위해서이다. return returnvalue; 첫째, 데이터베이스공급자에독립적인일관된데이터처리 API 사용둘째, 데이터베이스공급자별로다른예외처리클래스의일원화셋째, 선언적방식의트랜잭션처리전략 < 리스트 8> AOP 설정 XML 파일 // 설정파일에서타겟이될객체에대해서 AOP 를적용하고있다. <object id="aroundadvice" type="myapp.runningtimdaroundadvice, MyApp" /> <object id="mycommand" type="spring.aop.framework. ProxyFactoryObject"> <property name="target"> <object type=" MyApp.MyCommandObject, MyApp" /> </property> 그럼각각의목표를이루기위해제공되는 Spring.NET의세부기능들을보도록하자. ADO.NET의템플릿제공데이터베이스벤더별로서로다른 API를사용해야하는 ADO.NET의단점을개선하기위해서 Spring.NET은 Spring. Data 어셈블리를통해서 AdoTemplate 클래스를제공하고있다. AdoTemplate을사용하기위해서는데이터공급자를지정해 m a s o 265

스텝바이스텝 3 주어야하며현재 Spring.NET에서제공하는데이터공급자는 SQL 서버, 오라클, MySql, DB2 등이다. ( 그외의데이터공급자는 Spring.NET 매뉴얼을참조하자.) AdoTemplate은또한기존에 ADO.NET만을사용할때발생할수있는중복되는코드들을제거하고단순화해주는장점을가져다주며입력성쿼리를위한 ExecuteNonQuery, 단일값반환을위한 ExecuteScalar, 다중열형태로반환해주는 Query WithResultSetExtractor, QueryWithRowMapper, Query ForObject, DataTableCreate, DataSetCreate 등다양한메소드를지원해준다. 물론결과값반환시 Generic 형태도제공해주고있다. < 리스트 9>,< 리스트 10> 의코드는순수 ADO.NET 코드만을사용할때와 AdoTemplate을사용해서데이터액세스를할때의차이를잘보여주고있다. < 리스트 9> 순수 ADO.NET 만을사용할경우 public class PureAdoNetDao : IPureAdoNetDao { string connectionstring = "... 커넥션문자열... " public void Add(string id, string name, string address) { using (SqlConnection connection = new SqlConnection(connectionString)) { string sql = String.Format("insert into TestObjects(Id, Name, Address) " + "VALUES ('{0', '{1', '{2')", id, name, address); using (SqlCommand cmd = new SqlCommand(sql, connection) { connection.open(); comm.executenonquery(); < 리스트 10> AdoTemplate 을사용할경우 public class SpringDao : AdoDaoSupport, ISpringNetDao { public void Add(string id, string name, string address) { AdoTemplate.ExecuteNonQuery ( String.Format("insert into TestObjects(Id, Name, Address) " + "VALUES ('{0', '{1', '{2')", id, name, address)) 코드에서볼수있듯이순수 ADO.NET을사용할때보다코드의양도줄어들고, 그로인해발생할수있는에러확률도줄일 수있다. 또한데이터베이스별로다른 API(SQL 서버는 System.Data.SqlClient, 오라클은 System.Data.OracleClient 사용등 ) 를사용하던것을일관되게 AdoTemplate 클래스를사용하도록하여데이터베이스변경에따른코드변경의위험성을줄여준다. 이외에도데이터바인딩시 Null 처리자동화, 데이터처리시사용한객체의자동소멸등유용한기능이많이있으며이에대해서는 Spring.NET 매뉴얼을참조하길바란다. AdoTemplate을사용할경우에는어플리케이션의설정파일 (App.Config나 Web.Cofig 또는지정한설정파일 ) 에서앞서보았던 DI 방식을통해커넥션문자열을설정해준다. < 리스트 11> 의코드는설정파일에서커넥션문자열을설정하고 AdoTemplate의인스턴스를생성하는방식을보여주고있다. < 리스트 11> AdoTemplate 객체에데이터공급자를주입한다. <objects xmlns="http://www.springframework.net xmlns:db="http://www.springframework.net/ database"> <db:provider id="dbprovider" provider="sqlserver-2.0" connectionstring="data Source=(local);Initial Catalog=TEST_DB;Persist Security Info=True;User ID= 아이디 ;Password= 패스워드 "/> <object id="adotemplate" type="spring.data.core. AdoTemplate, Spring.Data"> <property name="dbprovider" ref="dbprovider"/> <object id="dao" type="mysample.springdao, MySample"> <property name="adotemplate" ref="adotemplate"/> </objects> 일관된예외처리 Spring.NET은또한데이터베이스벤더별로일관성없는예외처리를동일한예외처리클래스에서처리할수있도록일종의 translation 작업을지원해준다. 닷넷 1.1에서는데이터베이스벤더별로완전히다른예외처리클래스를사용해야했다. 예를들면, SQL 서버를쓸때는 System.Data.SqlClient.SqlException 클래스, 오라클을사용할때는 System.Data.OracleClient.OracleException 클래스에서제공하는예외클래스를사용해야했으며, 이는닷넷 2.0에서 System.Data.Common.DbException 클래스를제공함으로써조금향상되긴했지만, 여전히문제점을가지고있었다. 이러한단점을보완하고자 Spring.NET은데이터베이스벤더별로다른 266 m a s o

Spring.NET 애플리케이션프레임워크 예외를공통의클래스에서처리하도록지원해주고있으며, < 표 1> 은 Spring.NET에서제공하는예외클래스들중일부이다. 메소드에 [Transaction()] 어트리뷰트를선언하는것만으로트랜잭션처리를끝낼수있는것이다. Exception 설명 BadSqlGrammarException 수행한 SQL 의문법에오류가있을 경우 PermissionDeniedDataAccessException 특정테이블등의리소스에접근권 한이없을경우 DataAccessResourceFailureException 데이터베이스연결이실패한경우 DataIntegrityViolationException 중복키삽입등과같이데이터무결 성을위반하는에러가발생한경우 CannotAcquireLockException 업데이트하기위해데이터를가져 와야할경우처럼 DB Lock을얻 지못한경우 < 표 1> Spring.NET에서제공하는주요데이터액세스예외처리클래스 트랜잭션관리 다음으로 Spring.NET의데이터액세스기능이제공하는또 하나의큰장점은선언적방식의트랜잭션지원전략이다. Spring.NET 개발팀의리더를맡고있는 Mark Pollack은기 존에닷넷에서제공하는트랜잭션방식은닷넷 1.1 이후로계속 해서발전해왔지만, 여전한문제점을가지고있다고보았으며 < 표 2> 와같이닷넷에서제공하는트랜잭션방식을정리했다. Local Distributed Declarative Transaction Transaction ADO.NET O X X Enterprise Services X O O System.Transactions O O X < 표 2> 닷넷의트랜잭션지원현황 < 표 2> 에서보듯 Mark Pollack은닷넷에서제공하고있지못한로컬트랜잭션을사용하면서도선언적방식 (Attribute, XML 을사용 ) 의트랜잭션전략이필요하다고생각했으며 Spring. NET은위의 ADO.NET, Enterprise Services, System. Trans actions에서제공하는각각의트랜잭션지원기능을바탕으로각각에해당하는트랜잭션구현체를제공하고있다. - AdoPlatformTransactionManager - ADO.NET에기반한트랜잭션지원 - ServiceDomainPlatformTransactionManager - Enterprise Services 에기반한트랜잭션지원 - TxScopePlatformTransactionManager - System.Transactions에기반한트랜잭션지원즉, 개발자는 < 리스트 12>,< 리스트 13> 의코드처럼응용프로그램에필요한트랜잭션구현체를설정파일에선언하고필요한 < 리스트 12> 트랜잭션어트리뷰트를사용한코드 public class BankServiceObject : IBankServiceObject { // 기존의잡다한트랜잭션처리관련코드들은모두사라진다. [Transaction()] public void AddAccountAndMoney(Account account, int money) { string accountid = AccountDao.Create(account); AccountDao.Create(accountID, money); < 리스트 13> 설정파일에서의트랜잭션선언 // 코드에서트랜잭션을처리하는대신설정파일에서트랜잭션을선언한다. <db:provider id="dbprovider" provider="sqlserver-2.0" connectionstring="data Source=(local);Initial Catalog=TEST_DB;Persist Security Info=True; User ID= 아이디 ;Password= 패스워드 "/> <object id="transactionmanager" type="spring.data.adoplatformtransactionmanager, Spring.Data"> <property name="dbprovider" ref="dbprovider"/> <object id="adotemplate" type="spring.data.adotemplate, Spring.Data"> <property name="dbprovider" ref="dbprovider"/> <object id="accountdao" type="sample.bankdaoobject, SampleAssemply"> <property name="adotemplate" ref="adotemplate"/> <object id="bankserviceobject" type=""ample. BankServiceObject, SampleAssemply"> <property name="accountdao" ref="accountdao"> <tx:attribute-driven transaction-manager= "transactionmanager"/> 기존의트랜잭션처리방식보다스프링에서제공하는선언적트랜잭션방식의장점은코드에서매번반복되는트랜잭션처리코드를깔끔히제거할수있으며, 순수닷넷객체 (PONO) 만을사용하므로엔터프라이즈서비스처럼특정클래스로부터상속받지않아도된다는점, 로컬트랜잭션이든분산트랜잭션이든필요할때마다코드가아닌트랜잭션선언파일만을변경하면된다는점등이되겠다. m a s o 267

스텝바이스텝 3 분산프로그래밍지원 - Spring Services 마지막으로 Spring.NET에서제공하는분산프로그래밍기능에대해서알아보도록하자. Spring Services라고명명하고있는이기능은일명 PONO, 즉특정한클래스로부터상속받지않은순수닷넷객체를그대로활용하여웹서비스, 리모팅, 엔터프라이즈서비스로포팅한다. 이기능의장점은비즈니스레이어를일반클래스라이브러리형태로개발해놓고설정파일에서의변경만으로사용자의필요에따라세가지분산서비스형태를제공할수있다는것이다. 어떠한소프트웨어프로젝트를시작하면서개발전에미리분산서비스형태를웹서비스나리모팅, 엔터프라이즈서비스형태로확정짓고개발하게되면어플리케이션개발완료후서비스방식의변경에대한위험성이클수밖에없다. 하지만 Spring Services 기능을활용하게되면서비스방식을언제라도쉽게변경할수있으므로어플리케이션아키텍쳐를훨씬서비스독립적으로가져갈수있을것이다. 간단하게축약된코드를통해서 PONO 객체를웹서비스로포팅하는과정은 < 리스트 14> 와 < 리스트 15>,< 리스트 16>< 리스트 17> 을통해볼수있다. < 리스트 14> 웹서비스로포팅될비즈니스레이어코드 public class UserService : IUserService { public void AddUser(string name, string email) { // --- 로직코드 --- < 리스트 15> Web.Config // 웹프로젝트에서비즈니스객체를웹서비스로포팅한다. <object id="userservice" type="serviceapp.userservice, ServiceApp"/> // id 어트리뷰트의값을사용하여 "http:// URL 주소 /userwebservice.asmx" 로포팅됨. <object id="userwebservice" type="spring.web. Services.WebServiceExporter, Spring.Web"> <property name="targetname" value="userservice" /> <system.web> <httphandlers> <add verb="*" path="*.asmx" type="spring.web.services.webservicehandlerfactory, Spring.Web"/> </httphandlers> </system.web> 앞서설명된리스트에대해간단히설명을덧붙이자면, 일반클래스로만들어진 User Service 객체를 Spring.NET은 Web Service Exporter 클래스를통해서웹서비스로노출하며 http Handlers에 Web Service Handler Factory를등록하여일반객 < 리스트 16> 클라이언트에서웹서비스사용설정파일 <object id="userservice" type="spring.web.services. WebServiceProxyFactory, Spring.Services" > <property name="serviceuri" value="http:// URL 주소 /userwebservice.asmx"/> <property name="serviceinterface" value="serviceapp. IUserService, ServiceApp"/> <object id="myclient" type="clientapp.myclient, ClientApp"> <property name="userservice" ref="userservice" /> < 리스트 17> 웹서비스를사용하는클라이언트코드 public class MyClient { private IUserService userservice; public UserService { get { return userservice; set { this.userservice = value; public void MyTest() { // 웹서비스로포팅된 UserService 객체를사용하게됨. UserService.AddUser(" 권효중 ", "fog_rain@naver.com"); 체를마치웹서비스클래스와웹메소드처럼포팅한다. 이렇게웹서비스로포팅되면예제코드에서처럼 http:// URL 주소 /userwebservice.asmx 형태로웹서비스되고클라이언트에서는 DI 방식을사용하거나기존의방식처럼 WSDL을생성하여 ( 비주얼스튜디오를이용한자동이든수동이든상관없이 ) 사용할수도있다. 이로써 Spring.NET에서제공하는몇가지핵심기능들에대해서알아보았다. 지면관계상 Spring.NET의 ASP.NET Web Form 지원기능이라든지, WCF 지원기능등매력적인몇가지기능들에대해서다루지못한점이매우아쉽긴하지만 Spring. NET을처음접하는개발자들에겐그개념과활용방법을모색해볼수있는기회가되었기를바라며, 기사에서다하지못한이야기들은필자의블로그 (http://funnygangstar. tistory.com) 를통해서계속공유하도록하겠다. 다음호에서는닷넷환경에서사용할수있는오픈소스데이터베이스프레임워크인 ibatis.net에대해서알아보도록하겠다. 참고자료 Spring.NET 공식메뉴얼, http://www.springframework.net/documentation.html Introduction to Data Access with Spring.NET by Mark Pollack, SpringOne- DataAccess-Pollack.ppt 268 m a s o