1 / 27

㈜ 중외정보기술 권효중

Spring.Net v1.1 Quick Guide. ㈜ 중외정보기술 권효중. Inversion of Control. AOP. Data Access. Web Service. Overview. Sample. 2. 3. 4. 5. 1. 6. 목 차. 본 문서의 목적. 본 문서는 Spring.Net 프레임웍에 대한 사용자 가이드 역할을 합니다 .

jabir
Download Presentation

㈜ 중외정보기술 권효중

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Spring.Net v1.1 Quick Guide ㈜중외정보기술 권효중

  2. Inversion of Control AOP Data Access Web Service Overview Sample 2 3 4 5 1 6 목 차

  3. 본 문서의 목적 본 문서는 Spring.Net 프레임웍에 대한 사용자 가이드 역할을 합니다. 닷넷 기반 어플리케이션 구축에 필요한 Spring.Net의 기능들 중 가장 널리 쓰이는 기능들을 중심으로 실제 예제와 함께 설명하여 어플리케이션 구축시 Spring.Net을 쉽게 적용할 수 있도록함이 본 문서의 목적입니다. 본 문서는 작성자의 Spring.Net 프레임웍에 대한 이해에 기반하므로 오류가 있을 수 있음을 밝혀두며, 발견한 오류를 작성자 메일로 보내주시면 즉시 수정토록 하겠습니다. 수정 이력

  4. 1. Overview • 1. Spring.Net의 목적 및 배경 • : 스프링닷넷을 한마디로 정의하자면 제어의 역전(Inversion of Control)을 기반으로한 닷넷 기반 엔터프라이즈 어플리케이션을 구축하기 위한 어플리케이션 프레임웍이라고 할 수 있다. • IoC, AOP의 기반하에 실행되는 특성으로 인해 여타 다른 어플리케이션 프레임웍과는 달리 추가되는 라이브러리나 컴포넌트들과 유연하게 작동될 수 있으며, 스프링닷넷의 궁극적인 목적은 세세한 기능을 지원해 주는 라이브러리 성격의 프레임웍이 아닌 엔터프라이즈 어플리케이션 전체에 아키텍쳐를 견고하게 구축해주는 뼈대 역할을 하는 것이다. • 위의 그림에서 보듯이 스프링닷넷은 IoC, AOP의 기반위에 Web, Data Access, ORM, Service 기능을 지원하고 있다. • 스프링닷넷을 사용하는 목적과 그 효과는 다양하지만, 그 중에서도 레이어간의 느슨한 결합(Loose Coupling)을 통한 컴포넌트화의 극대화, 주관심사(Core Concerns)에만 집중할 수 있는 개발 환경 지원으로 인한 개발속도 향상이라고 할 수 있을 것이다. Aspected Oriented Programming (AOP) ORM Nhibernate, iBatis.Net others Web Dependency Injection for ASP.NET & Web Services Master Pages, Biderectional Data Binding, Localization Data Transaction Infrastructure ADO.NET support DAL support Services Windows Services Remoting Web Services COM+ Enterprise Services CORE Inversion of Control Container Supporting Utilities (Collections, Threading, Pooling)

  5. 1. Overview • 2. 설치 및 사용방법 • : 스프링닷넷의 공식 웹사이트는 http://www.springframework.net 이다. • 이곳에서 좌측 메뉴의 “Downloads”를 클릭해서 Sourceforge로 이동한후 최신 • 버전을 다운받아서 설치한다. • 2007년 10월 9일 현재 최신 버전은 “Spring.NET-1.1-RC1.exe”이다. • 설치한후 프로그램 목록에 보면 다음과 같이 설치되며 매뉴얼 문서, 예제 샘플이 제공된다. • 비쥬얼스튜디오에서 참조하는 방법은 아래와 같이 설치경로의 bin 폴더에 있는 라이브러리를 직접 참조하면 된다.

  6. 2. Inversion of Control • 1. IApplicationContext 인터페이스의 역할 및 Dependency Lookup • : Application Context는 Spring.Net에서 관리하는 객체의 생성과 소멸 등 일련의 작업을 하기 위한 컨테이너라고 볼 수 있다. • 예를 들어, Spring.Net 프레임웍에서 ExampleObject 라는 객체를 관리한다면 이 객체의 인스턴스는 Application Context라는 컨테이너에 키와 값의 쌍으로 저장되어 있으며 프로그램에서 ExampleObject 객체를 사용하려고 하면 Spring.Net 프레임웍은 해당하는 Application Context에서 키를 조회하여 값에 해당하는 인스턴스를 리턴하는 방식이다. • <configuration> • <configSections> • <sectionGroup name="spring"> • <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/> • <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/> • </sectionGroup> • </configSections> • <spring> • <context> • <resource uri="config://spring/objects"/> • </context> • <objects xmlns="http://www.springframework.net"> • ... 사용할 객체 선언 ... • </objects> • </spring> • </configuration> • 윈폼이나 웹폼의 응용 프로그램 구성 파일에서 위와 같이 Application Context를 지정한 후, 프로그램에서는 아래와 같이 호출하여 사용한다. • IApplicationContext ctx = ContextRegistry.GetContext(); • IDAO dao = ctx.GetObject("dao") as IDAO; • 물론 Web.config나 App.config 파일외의 별도 XML 파일에서 관리하는 것도 역시 가능하다. 단, 이 경우 주의할 점은 Visual Studio에서 별도의 XML 파일 속성 중 빌드 작업 속성을 ‘포함 리소스’로 빌드해야만 파일을 인식할 수 있다. • 쉽게 생각하면, 결국 Application Context는 마치 어플리케이션 전체를 관할하는 전역 변수나 인스턴스와 같은 역할을 한다고도 볼 수 있다.

  7. 2. Inversion of Control • 2. 객체의 생성과 소멸 • : 스프링닷넷 컨테이너는 설정파일을 사용하여 객체를 생성할 수 있다. • <object id=“exampleObject” type=“Examples.ExampleObject, ExampleLibrary”/> • App.config나 web.config에서 위와 같이 선언하면 exampleObject가 생성된다. • id 어트리뷰트는 설정파일 내에서 사용할 객체의 이름이며, name 어트리뷰트도 동일한 기능을 한다. type 어트리뷰트에는 생성할 객체의 어셈블리 이름과 네임스페이스 경로를 기재하면 된다. • 단, 이 경우 ExampleObject는 아규먼트 없는 디폴트 생성자를 가지고 있어야 한다. • 객체의 생성과 소멸시 각각 호출되는 메소드를 정의할 수 있다. • <object id="dao" • type="MySpringSample_03.DAO, MySpringSample_03" • init-method="Init" • destroy-method="Finish“ • singleton="true“ • lazy-Init=“true”/> • 스프링닷넷 프레임웍에 의해 관리되는 객체들은 기본적으로 모두 Singleton 방식으로 생성된다. Singleton 방식으로 생성하지 않으려면 singleton="false“ 로 설정한다. 디폴트는 true이다. • 웬만한 객체들은 Singleton 방식으로 생성하는 것이 가급적 메모리의 사용을 줄이는 방법이 될 수 있을 것이다. • lazy-Init 속성은 객체를 생성할 때 어플리케이션 로드시에 생성하는 것이 아니라 객체가 최초 호출될때 생성하는 방식으로써 어플리케이션 로드에 걸리는 부담을 경감시켜주는 효과가 있다.

  8. 2. Inversion of Control • 3. Dependency Injection • : 스프링닷넷 프레임웍은 설정 파일 내에서 객체간의 의존 관계를 설정할 수 있다. 이는 디자인패턴의 Factory Method Pattern에서의 팩토리 클래스와 같은 효과를 가진다. • <object id=“service” type=“ServiceLayer.Service, ServiceLayer”> • <property id=“Dao” ref=“dao”/> • </object> • <object id=“dao” type=“DaoLayer.DAO, DaoLayer”> • 위의 설정은 Service 클래스에서 Property 메소드를 사용해서 DAO 클래스의 인스턴스를 획득하고 있다. • //Service.cs • public class Service : IService • { • private IDAO dao; • public IDAO Dao • { • set { dao = value; } • } • public string SayHello(string name) • { • return dao.HelloDAO(name + " " + TestValue); • } • } • //DAO.cs • public class DAO : IDAO • { • public string HelloDAO(string name) • { • return "HELLO " + name + " FROM DAO"; • } • } • 단, Property를 이용하여 DI를 구현할 경우에는 사용하는 클래스의 디폴트 생성자(아규먼트없는 public 생성자)를 가지고 있어야 하며, 부득이하게 private 으로 선언하여야 할 경우에는 다음으로 소개할 <constructor-arg> 엘리먼트를 사용하여야 한다. • <object id=“service” type=“ServiceLayer.Service, ServiceLayer”> • < constructor-arg name=“Dao” ref=“dao”/> • </object>

  9. 2. Inversion of Control • //Service.cs • public class Service : IService • { • private DAO dao; • private Service(){} • private Service(DAO dao) • { • this.dao = dao; • } • public string SayHello(string name) • { • return dao.HelloDAO(name + " " + TestValue); • } • } • 그러나, 위와 같이 구현할 경우는 그리 많지 않을것이며, 스프링닷넷 프레임웍의 개발 리드를 맡고 있는 Mark Polarck 또한 Property 를 이용한 DI 사용을 권장하고 있다. • 이처럼, DI 기능을 사용하여 객체를 생성하는 방법에는 Property를 이용하는 방법과 생성자를 이용하는 방법 두가지가 있다. • ASP.NET에서는 웹어플리케이션이 로드될 때 자동적으로 IApplicationContext를 로딩해준다. 따라서 웹페이지에서는 바로 DI 기능을 사용할 수 있다. 하지만 윈폼에서는 아직 IApplicationContext의 로딩을 자동화해주지 않으므로 최초에 한번은 프로그래머가 직접 로딩해 주어야 한다. • // Program.cs • static class Program { • [STAThread] • static void Main() { • try { • Application.EnableVisualStyles(); • Application.SetCompatibleTextRenderingDefault(false); • // ApplicationContext를 로딩 • IApplicationContext ctx = ContextRegistry.GetContext(); • Form mainForm = (Form)ctx["mainForm"]; • Application.Run(mainForm); • } catch(Exception x) {} • } • } • // App.Config • <object id="mainForm" type=“TestNS.frmMain, TestNS"></object>

  10. 2. Inversion of Control • 4. 설정파일에서의 ApplicationContext 설정방법 • : 아래는 일반적인 설정파일의 형태이다. configSections 엘리먼트내에서 spring 섹션 그룹을 설정하고 그 내부에 context, objects 섹션을 설정한다. • <?xml version="1.0" encoding="utf-8" ?> • <configuration> • <configSections> • <sectionGroup name="spring"> • <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" /> • <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> • </sectionGroup> • </configSections> • <spring> • <context> • <resource uri="config://spring/objects"/> • </context> • <objects xmlns="http://www.springframework.net"> • <object id="dao" type="MySpringSample_05.DAO, MySpringSample_05" > • </object> • <object id="serviceBase" type="MySpringSample_05.ServiceBase, MySpringSample_05"> • <property name="Dao" ref="dao"/> • </object> • <object id="service" • type="MySpringSample_05.Service, MySpringSample_05" • parent="serviceBase" • singleton="true" • lazy-init="true" > • </object> • </objects> • </spring> • </configuration> • 설정할 내용이 많을 경우 objects 엘리먼트의 내용은 부속 xml 파일로 빼낼 수 있다. 그러기 위해서는 다음과 같이 지정한다. 단, 주의할 점은 부속 xml 파일의 빌드 속성을 “포함 리소스”로 변경하는것을 절대 잊어선 안된다. • <spring> • <context type="Spring.Context.Support.XmlApplicationContext, Spring.Core"> • <resource uri="file://objects.xml"/> • <resource uri="assembly://MyAssembly/MyProject/objects-dal-layer.xml"/> • </context> • </spring>

  11. 3. AOP • 1. AOP의 개념 • : Aspected Oriented Programming 을 우리말로 굳이 번역하자면 관점 지향 프로그래밍 정도일것이다.(아마도 더 헷갈릴듯 -.-) 여기서 말하는 관점을 주관심사(Core Concerns)와 횡단관심사(Cross Cutting Concerns)로 나눌 수 있는데, 주관심사는 비즈니스 로직이 될 수 있고, 횡단관심사는 비즈니스 로직에 사용되는 로깅, 트랜잭션, 인증 등과 같은 로직들이다. • 어플리케이션을 개발하는동안 개발자는 주관심사만 개발하는 것이 아니라 어쩔 수 없이 횡단관심사도 개발해야만 한다. AOP에서는 개발자는 주관심사에만 집중하고 횡단관심사들은 컨테이너에 맡겨버려서 개발 속도를 향상시키고 객체지향의 원래 목적에 더욱 더 충실하자는 것이 AOP가 지향하는 목적이라고 볼 수 있다. 로 깅 (메소드 호출, 예외 처리 등) 주관심사 트 랜 잭 션 처 리 회원정보조회 회원 등록 회원 탈퇴 인 증 (접근 제한, 자격 관리) { 횡단 관심사

  12. 3. AOP • 2. AOP의 주요 용어 정리 • Joinpoint • AOP에서 Jointpoint는 클래스의 인스턴스 생성 시점, 메쏘드를 호출하는 시점, Exception이 발생하는 시점과 같이 애플리케이션을 실행할 때 특정 작업이 실행되는 시점을 의미한다. • Target • 실질적인 비즈니스 로직 부분. • 주관심사. • Advice • Logging, Exception, Transaction, Email, Message, Security 등과 같이 실질적인 비즈니스 로직(Target, 횡단 관심사)에 추가적인 기능을 제공하는 것을 말한다. • 횡단 관심사. 스프링닷넷 프레임웍에서 제공하는 Advice에는 before, after, around, throws가 있다. • Pointcut • 분리된 기능들(Target과 Advice, 종단 관심사와 횡단 관심사 )을 결합시키기 위한 규칙(패턴) • Aspect • Advice와 Pointcut을 합쳐서 하나의 Aspect라고 한다. 즉, 일정한 패턴을 가지는 클래스에 Advice를 적용하도록 지원할 수 있는 것을 Aspect라고 한다. • 애플리케이션 개발을 위하여 세운 일정한 패턴을 가진 정책. • 예) 로깅은 메쏘드 시작과 끝 지점에 남긴다. • Weaving • Target과 Advice를 결합시키는 것을 의미한다. 분리하여 개발된 기능들을 Weaving하는 작업을 도와주는 것이 AOP 툴이 하는 역할이다. • - 스프링프레임워크 워크북(박재성 저)에서 발췌

  13. 3. AOP • 3. before, around, after, throws advice • : 스프링닷넷에서 제공하는 Advice에는 before, around, after, throws 네가지가 있다. 단어에서 유추할 수 있듯이 before는 특정 메소드가 호출되기전에 인터셉트됨을 의미하며, around는 메소드가 실행되기 바로 전과 후에, after는 실행 직후에, throws는 예외가 발생했을때 인터셉트된다. • 1) before Advice 구현 • public class CountingBeforeAdvice : IMethodBeforeAdvice { • public void Before(MethodInfo method, object[] args, object target) { • Console.WriteLine(“메소드 호출전”); • } • } • : before Advice는 IMethodBoforeAdvice 인터페이스를 구현한 클래스의 Before 메소드에서 실행된다.

  14. 3. AOP • 2) around Advice 구현 • public class DebugInterceptor : IMethodInterceptor { • public object Invoke(IMethodInvocation invocation) { • Console.WriteLine(“메소드 실행전”); • object rval = invocation.Proceed(); • Console.WriteLine(“메소드 실행직후"); • return rval; • } • } • : around Advice는 IMethodInterceptor 인터페이스를 구현한 클래스의 Invoke 메소드에서 실행된다. 인자로 전달받은 invocation의 Proceed 메소드가 실행될때 타겟 메소드가 실행된다. • 3) after Advice 구현 • public class CountingAfterReturningAdvice : IAfterReturningAdvice { • public void AfterReturning(object returnValue, MethodBase m, object[] args, object target) { • Console.WriteLine(“메소드 실행 직후”); • } • } • : after Advice는 타겟 메소드가 실행된 직후에 IAfterReturningAdvice 인터페이스를 구현한 클래스의 AfterReturning 메소드가 실행된다. • 4) throws Advice 구현 • public class CombinedThrowsAdvice : IThrowsAdvice { • public void AfterThrowing(RemotingException ex) { • // Do something with remoting exception • } • public void AfterThrowing(MethodInfo method, object[] args, object target, SqlException ex) { • // Do something will all arguments • } • } • : throws Advice는 예외가 발생될 때 IThrowsAdvice 인터페이스를 구현한 클래스의 AfterThrowing 메소드가 실행된다. • AfterThrowing 메소드의 인자로 특정 Exception 객체를 선언하면 해당 예외가 발생할 때만 호출된다.

  15. 3. AOP • 4. Aspect 설정 방법 • <objects xmlns='http://www.springframework.net'> • <object id="beforeAdvice" • type="MySpringSample_AOP.AspectObject.BeforeLog, MySpringSample_AOP" /> • <object id="afterAdvice" • type="MySpringSample_AOP.AspectObject.AfterLog, MySpringSample_AOP" /> • <object id="aroundAdvice" • type="MySpringSample_AOP.AspectObject.AroundLog, MySpringSample_AOP" /> • <object id="throwsAdvice" • type="MySpringSample_AOP.AspectObject.ExceptionLog, MySpringSample_AOP" /> • <object id="DAOproxy" type="Spring.Aop.Framework.ProxyFactoryObject"> • <property name="Target"> • <object type="MySpringSample_AOP.DAO, MySpringSample_AOP" /> • </property> • <property name="InterceptorNames"> • <list> • <value>beforeAdvice</value> • <value>afterAdvice</value> • <value>aroundAdvice</value> • <value>throwsAdvice</value> • </list> • </property> • </object> • </objects> • : Aspect를 설정하는 방법은 위에서 보듯이 Advice들을 구현한 object를 선언한 후에 타겟 객체를 지정하면 해당 객체의 메소드가 실행될 때 “interceptorNames”Property의 “list”엘리먼트에서 지정한 Advice들이 해당 메소드의 실행을 가로채게 된다. 즉, 위에서는 DAO 객체의 메소드가 실행될 때 Advice가 작동하게 되는것이다.

  16. 3. AOP • 5. AutoProxy • : Auto Proxy 기능은 특정 클래스나 특정 메소드들만 Aspect 할 수 있는 기능을 말한다. 이 기능을 사용하면 객체들마다 Aspect를 설정해야하는 번거로움을 제거할 수 있다. • 1) 객체 이름(Object 엘리먼트의 id 값)을 기준으로 Aspect • 특정 클래스명을 가진 객체를 Aspect 하기 위해서는 ObjectNameAutoProxyCreator를 구현한다. 아래의 설정 예제를 보자. • <object id="aroundAdvice" • type="MySpringSample_AOP.AspectObject.AroundLog, MySpringSample_AOP" /> • <object id="ProxyCreator" • type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop"> • <property name="ObjectNames"> • <list> • <value>DAO*</value> • </list> • </property> • <property name="InterceptorNames"> • <list> • <value>aroundAdvice</value> • </list> • </property> • </object> • <object id="DAOproxy" type="MySpringSample_AOP.DAO, MySpringSample_AOP" /> • 위의 예제에서는 “DAO”이름으로 시작하는 id를 가진 모든 객체의 메소드를 Aspect하게된다.

  17. 3. AOP • 2) 메소드 이름을 기준으로 Aspect • : 메소드 이름을 기준으로 Auto Proxy를 구현하기 위해서는 NameMatchMethodPointcutAdvisor를 사용해야한다. • <object id="aroundAdvice" • type="MySpringSample_AOP.AspectObject.AroundLog, MySpringSample_AOP" /> • <object id="aroundAdvisor" • type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop"> • <property name="Advice" ref="aroundAdvice"/> • <property name="MappedNames"> • <list> • <value>Save*</value> • </list> • </property> • </object> • <!– DAO 객체에만 지정 --> • <object id="DAOproxy" type="Spring.Aop.Framework.ProxyFactoryObject"> • <property name="Target"> • <object type="MySpringSample_AOP.DAO, MySpringSample_AOP" /> • </property> • <property name="InterceptorNames"> • <list> • <value>aroundAdvisor</value> • </list> • </property> • </object> • <!-- 모든 객체에 지정 --> • <object id="DAOproxy" type="MySpringSample_AOP.DAO, MySpringSample_AOP" /> • <object type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop" /> • --> • 위의 예제에서는 DAO 객체의 Save로 시작하는 메소드의 경우에만 Aspect를 실행한다. • 물론, 객체명과, 메소드명을 혼합해서 사용하는 것도 가능하다. • 또, 주석처리 되어있는 DefaultAdvisorAutoProxyCreator를 사용하면 context에 지정된 모든 객체의 Save로 시작하는 메소드를 대상으로 Aspect를 실행할 수도 있다.

  18. 4. Data Access • 1. dbProvider • : 스프링닷넷에서 제공하는 데이타베이스 provider는 아래와 같다. • SqlServer-1.1 - Microsoft SQL Server, provider V1.0.5000.0 in framework .NET V1.1 • SqlServer-2.0 (aliased to System.Data.SqlClient) - Microsoft SQL Server, provider V2.0.0.0 in framework .NET V2.0 • SqlServerCe-3.1 (aliased to System.Data.SqlServerCe) - Microsoft SQL Server Compact Edition, provider V9.0.242.0 • OleDb-1.1 - OleDb, provider V1.0.5000.0 in framework .NET V1.1 • OleDb-2.0 (aliased to System.Data.OleDb) - OleDb, provider V2.0.0.0 in framework .NET V2.0 • OracleClient-2.0 (aliased to System.Data.OracleClient) - Oracle, Microsoft provider V2.0.0.0 • OracleODP-2.0 (aliased to System.DataAccess.Client) - Oracle, Oracle provider V2.102.2.20 • SQLite-1.0.43 - (aliased to System.Data.SQLite) - SQLite provider 1.0.43 for .NET Framework 2.0 • (MySql과 DB2는 매뉴얼을 참조하길 바람) • 설정파일에서는 아래와 같이 지정한다. • <objects xmlns='http://www.springframework.net' • xmlns:db="http://www.springframework.net/database"> • <db:provider id=“dbProvider" • provider=“SqlServer-2.0“ (또는, provider=“System.Data.SqlClient”) • connectionString="Data Source=(local);Database=Spring;User ID=springqa;Password=springqa;Trusted_Connection=False"/> • <object id="adoTemplate" type="Spring.Data.AdoTemplate, Spring.Data"> • <property name="DbProvider" ref=“dbProvider"/> • </object> • </objects>

  19. 4. Data Access • 2. AdoTemplate • : 스프링닷넷은 데이타베이스 액세스를 위한 간편한 랩퍼클래스를 제공하며, 그것이 AdoTemplate이다. AdoTemplate은 CRUD를 위한 다양한 메소드를 제공하고 있다. • 입력성 쿼리를 위한 ExecuteNonQuery, 단일값 반환을 위한 ExecuteScalar, 로우값을 사용자 지정 객체로 반환해주는 QueryWithResultSetExtractor, QueryWithRowMapper, QueryForObject 데이타셋이나 데이타테이블로 결과값을 반환해 주는 DataTableCreate, DataSetCreate 등 다양한 메소드를 지원해 준다. • <objects xmlns="http://www.springframework.net" • xmlns:db="http://www.springframework.net/database"> • <db:provider id="dbProvider" • provider="SqlServer-2.0" • connectionString="Data Source=khjnote;Initial Catalog=TEST_DB;Persist Security Info=True;User ID=sa;Password=showmethepower"/> • <object id="adoTemplate" type="Spring.Data.Core.AdoTemplate, Spring.Data"> • <property name="DbProvider" ref="dbProvider"/> • </object> • <object id="dao" type="MySpringSample_06.DAO, MySpringSample_06"> • <property name="AdoTemplate" ref="adoTemplate"/> • </object> • </objects> • public class DAO : AdoDaoSupport, IDAO { • public void Insert(string logonid, string name) { • string query = "insert into users(logonid, name) values(@logonid, @name)"; • IDbParametersBuilder builder = CreateDbParametersBuilder(); • builder.Create().Name("logonid").Value(logonid); • builder.Create().Name("name").Value(name); • AdoTemplate.ExecuteNonQuery(CommandType.Text, query, builder.GetParameters()); • } • } • 위 예제는 AdoTemplate을 통해서 데이터를 입력하고 있으며, 설정파일에서 DbProvider를 DAO 클래스의 AdoTemplate에 지정하였다.

  20. 4. Data Access • : 아래의 예제는 여러줄의 데이터를 IList 타입의 사용자 지정 객체로 반환받고 있다. • // DAO.cs • public class DAO : AdoDaoSupport, IDAO { • public IList SelectAll() { • string query = "select logonid, name from users"; • return AdoTemplate.QueryWithRowMapper(CommandType.Text, query, new UserMapper()); • } • } • // UserMapper.cs • public class UserMapper : IRowMapper { • public object MapRow(System.Data.IDataReader reader, int rowNum) { • UserEntity userEntity = new UserEntity(); • userEntity.Logonid = reader.GetString(0); • userEntity.Name = reader.GetString(1); • return userEntity; • } • } • // UserEntity.cs • [Serializable] • public class UserEntity • { • private string logonid; • private string name; • public string Logonid • { • get { return logonid; } • set { logonid = value; } • } • public string Name • { • get { return name; } • set { name = value; } • } • } • UserMapper 객체를 통해 데이타리더로 받은 결과로우를 UserEntity 객체 콜렉션으로 반환하고 있다.

  21. 4. Data Access • 3. 네임스페이스 파서 • : 설정파일에서 주의할점으로 네임스페이스 파서를 반드시 등록하는 것이다. • 그렇지 않으면 설정파일의 스키마를 해석하지 못하는 오류가 발생한다. • <?xml version="1.0" encoding="utf-8" ?> • <configuration> • <configSections> • <sectionGroup name="spring"> • <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" /> • <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> • <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core" /> • </sectionGroup> • </configSections> • <spring> • <parsers> • <parser type="Spring.Data.Config.DatabaseNamespaceParser, Spring.Data" /> • <parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data" /> • </parsers> • <context> • <resource uri="assembly://MySpringSample_06/MySpringSample_06/Service.xml"/> • <resource uri="assembly://MySpringSample_06/MySpringSample_06/DAO.xml"/> • </context> • </spring> • </configuration> • DatabaseNamespaceParser는 xmlns:db="http://www.springframework.net/database“ 스키마를 파싱하도록 도와주며, TxNamespaceParser는 xmlns:tx="http://www.springframework.net/tx“ 스키마를 파싱하도록 도와주는 역할을 실행한다.

  22. 4. Data Access • 4. 트랜잭션 전략 • : 스프링닷넷에서 트랜잭션을 제어하기 위해서는 해당 메소드에 [Transaction] 어트리뷰트를 선언하고 설정파일에서는 아래의 코드를 삽입한다. • <object id="transactionManager" • type="Spring.Data.Core.TxScopeTransactionManager, Spring.Data"> • </object> • <tx:attribute-driven transaction-manager="transactionManager"/> • 또한 트랜잭션 네임스페이스 파서를 등록하는 것을 잊지 않도록 한다. • <parser type="Spring.Transaction.Config.TxNamespaceParser, Spring.Data" /> • [Transaction] • public void CreateUser(string logonid, string name) • { • Dao.Insert(logonid, name); • throw new Exception("강제 예외 실행"); • Dao.Insert(logonid, name); • } • 아래는 특정 메소드에만 트랜잭션을 설정하는 방법이다. Create로 시작하는 메소드는 모두 트랜잭션 기능이 적용된다. • <tx:advice id="txAdvice" transaction-manager="transactionManager"> • <tx:attributes > • <tx:method name="Create*"/> • </tx:attributes> • </tx:advice> • 트랜잭션에 관해서는 다양한 옵션이 존재하므로 매뉴얼을 참조하길 바람. • 주의 : 스프링닷넷의 트랜잭션을 사용하기 위해서는 반드시 인터페이스를 구현해야함.

  23. 5. WebService • 1. Server Side • : 스프링닷넷에서는 PONO를 설정만으로 손쉽게 웹서비스, 엔터프라이즈 서비스, 닷넷리모팅으로 포팅해준다. 스프링닷넷팀이 웹서비스를 지원하게된 이유는 1.별다른 사용용도가 없는 *.asmx 파일을 제거하고, 2.웹서비스에서도 DI 기능을 지원하고, 3.PONO를 그대로 웹서비스로 포팅하며, 4.클라이언트 영역에서 웹서비스를 일반 라이브러리에 접근하듯이 손쉽게 사용하기 위해서이다. • 스프링닷넷의 웹서비스 기능을 사용하기 위해서는 PONO 객체와 이를 호스팅해줄 웹사이트를 준비해야한다. • namespace HelloWorldApp • { • public interface IHelloWorld { • string HelloWorld(); • } • public class HelloWorldService:IHelloWorld • { • private string message; • public string Message { • set { message = value; } • } • public string HelloWorld() { • return this.message; • } • public string SayNo() { • return "No"; • } • } • } PONO - WebServiceExporter - WebServiceHandlerFactory - WebSupportModule ① 컴파일, 프락시확인 WS consumer IIS (Webservice Hosting) ② Request 전송 스프링닷넷의 웹서비스를 사용하기위해 PONO 측에서 해야할 단 한가지의 작업이 있는데 그것은 인터페이스를 구현해야한다는 점이다. 그리고 인터페이스에서 선언한 메소드들만이 WebServiceExporter에 의해 웹메소드로 사용될 수 있다.

  24. 5. WebService • : 다음은 PONO를 웹서비스로 포팅할 웹사이트의 Web.Config 이다. (일부발췌.) • <objects xmlns="http://www.springframework.net"> • <object id="helloWorld" type="HelloWorldApp.HelloWorldService, HelloWorldApp"> • <property name="Message" value=“안녕하세요!"/> • </object> • <object id="HelloWorldService" type="Spring.Web.Services.WebServiceExporter, Spring.Web"> • <property name="TargetName" value="helloWorld"/> • <property name="Namespace" value="http://MySpringSample_WS/HelloWorldService"/> • </object> • </objects> • <system.web> • <httpHandlers> • <add verb="*" path="*.asmx" • type="Spring.Web.Services.WebServiceHandlerFactory, Spring.Web"/> • </httpHandlers> • <httpModules> • <add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/> • </httpModules> • </system.web> • 설정이 완료되었으면 디폴트페이지에 링크를 걸어 HelloWorldService.asmx를 확인한다. • <body> • <table width="100%" height="100%" align="center" valign="middle"> • <tr> • <td align="center"> • <h2><a href="HelloWorldService.asmx">helloWorldService</a></h2> • </td> • </tr> • </table> • </body> http://웹사이트이름 /HelloWorldService.asmx 로 서비스됨.

  25. 5. WebService • 2. Client Side • : 클라이언트에서는 PONO 모듈을 참조한 후에 설정 파일에서 해당 웹서비스를 사용하겠다는 선언을 하면된다. • <object id="helloWorldService" • type="Spring.Web.Services.WebServiceProxyFactory, Spring.Services"> • <property name="ServiceUri" value="http://localhost/HelloWorldWeb/helloworldservice.asmx"/> • <property name="ServiceInterface" value="HelloWorldApp.IHelloWorld, HelloWorldApp"/> • <property name="ProductTemplate"> • <object> • <property name="Timeout" value="10000" /> 웹메소드를 호출후 기다리는 시간 10초 설정 • </object> • </property> • </object> • 설정 파일에서는 위의 설정만으로 충분하며 클라이언트 코드에서는 일반적인 DI 기능을 사용하듯이 사용하면 된다. • private IHelloWorld serviceHello; • public IHelloWorld ServiceHello • { • get { return serviceHello; } • set { serviceHello = value; } • } • private void button1_Click(object sender, EventArgs e) • { • string s = ServiceHello.HelloWorld(); • MessageBox.Show(s); • }

  26. 6. Sample • 샘플 #1. • - MySpringSample_01 • : 기본적인 IoC 기능 구현 • 샘플 #2. • - MySpringSample_02, MySpringSample_03 • : 기본 설정 파일이 아닌 외부에서 XML 파일로 IoC 기능을 설정하는 방법 • : Application Context를 헬퍼파일로부터 생성하는 방법 • 샘플 #3. • - MySpringSample_04 • : 간단한 AOP 기능 구현 • 샘플 #4. • - MySpringSample_05 • : 객체 생성시 다양한 옵션 활용법 • : IoC를 이용한 상속 기능 활용 • 샘플 #5. • - MySpringSample_06 • : 트랜잭션 설정 방법 • 샘플 #6. • - MySpringSample_07 • : Winform에서 우회적으로 DI를 사용하는 방법 • 샘플 #7. • : 웹서비스 기능 샘플 • - HelloWorldApp • : PONO 비즈니스 모듈 • - HelloWorldWeb • : HelloWorldApp를 웹서비스로 호스팅해줄 웹사이트 • - MySpringSample_WS_Client • : 웹서비스를 사용하는 클라이언트

  27. 부 서 : ㈜중외정보기술 개발본부 연구팀 • 성 명 : 권효중 • 메 일 : khj@cwit.co.kr, fog_rain@naver.com • 전 화 : 016-676-1072 • 주 소 : 서울시 구로구 구로3동 이앤씨벤처드림타워6차 1002호 감사합니다.

More Related