Spring 프레임워크의 이해 – day2 자바지기.

Slides:



Advertisements
Similar presentations
Transaction ㅇ Transaction 을 직접 구현하려면, 까다로운 설계와 복잡한 코드를 필요로 하고 수정에 공수가 많이 들게 된다. ㅇ 스프링에서 제공하는 Transaction Manager 를 사용하여 쉽고 간편하게 어려운 트랜잭션을 해결할 수 있다. xml.
Advertisements

2008 년 11 월 20 일 실습.  실험제목 ◦ 데이터베이스 커넥션 풀  목표 ◦ 데이터베이스 커넥션 풀의 사용.
뇌를 자극하는 SQL Server 장. 트랜잭션과 잠금. 뇌를 자극하는 SQL Server 장. 트랜잭션과 잠금 2 / 18 트랜잭션 개념과 문법 트랜잭션 개념  하나의 논리적 작업단위로 수행되는 일련의 작업  전부 되거나, 전부 안 되거나의.
목 차 C# 언어 특징 .NET 프레임워크 C# 콘솔 프로그램 C# 윈도우 프로그램 실습 프로그래밍세미나 2.
Chapter 16 : Struts 프레임워크 2. chapter 16 : Struts 프레임워크 2.
10. 예외 처리.
PARK SUNGJIN Oracle 설치 PARK SUNGJIN
DB 프로그래밍 학기.
DB 프로그래밍 학기.
소프트웨어시스템설계(6주) 데이터베이스 연동
제 08 장 자바 빈즈 학기 인터넷비즈니스과 강 환수 교수.
JPetStore 분석자료 1.0 Spring framework 작성자 : 김태완.
제 09 장 데이터베이스와 MySQL 학기 인터넷비즈니스과 강 환수 교수.
DB와 WEB 연동(1) [2-Tier] Java Applet 이용
객체 지향 원리 송치형.
IOC, DI 2015 Web Service Computing.
5장 Mysql 데이터베이스 한빛미디어(주).
AOP 개념 및 Spring의 AOP 기능.
4장. 웹로직 서버상에서의 JDBC와 JTA의 운용
Lesson 9. 예외처리.
Struts2 를 이용한 SOCAS Homepage
Spring Framework JDBC, Transaction
자바 5.0 프로그래밍.
                              데이터베이스 프로그래밍 (소프트웨어 개발 트랙)                               퍼스널 오라클 9i 인스톨.
모바일 자바 프로그래밍 JDBC / WAP Ps lab 오민경.
18강. 데이터 베이스 - II JDBC 살펴보기 Statement객체 살펴보기 Lecturer Kim Myoung-Ho
17강. 데이터 베이스 - I 데이터 베이스의 개요 Oracle 설치 기본적인 SQL문 익히기
KHS JDBC Programming 4 KHS
YOU Youngseok 트랜잭션(Transaction) YOU Youngseok
Chapter 03 : 서블릿 ( Servlet ) 개요. chapter 03 : 서블릿 ( Servlet ) 개요.
5장 Mysql 데이터베이스 한빛미디어(주).
10장. 예외처리.
속성과 리스너 초기화 파라미터 외 파라미터에 대해 이해한다. 리스너를 생성해보고 사용에 대해 이해한다.
You YoungSEok Oracle 설치 You YoungSEok
ㅇ 스프링 설정파일 (dispatcher-servlet.xml)
JDBC (Java Database Connectivity)
AOP (Aspect Oriented Programing)
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
개발 환경 세팅.
2장. 데이터베이스 관리 시스템 데이터베이스 관리 시스템의 등장 배경 데이터베이스 관리 시스템의 정의
Spring 프레임워크의 이해 2. Spring Introduction.
3. Spring 프레임워크의 IoC 컨테이너 개념
Spring 프레임워크의 이해 1.Architecture.
뇌를 자극하는 Windows Server 2012 R2
Spring 프레임워크의 이해 – day1 자바지기.
Spring 프레임워크의 이해 3. Spring IoC 이해 및 활용.
15장 컬렉션 프레임워크 Section 1 컬렉션 프레임워크의 개요 Section 2 리스트 Section 3 셋
SpringFramework 중간고사 요약 REST by SpringFramework.
컴퓨터공학실습(I) 3주 인공지능연구실.
Spring DI 이해 및 활용.
Spring Framework 플랫폼개발실 김광욱
기말 프로젝트 계획 MVC 패턴 기반 웹 애플리케이션 개발 프로젝트명 : 팀명 : 팀원 :
Spring Security 2015 Web Service Computing.
5.2 트랜잭션 서비스 추상화.
CHAP 21. 전화, SMS, 주소록.
4. Spring 프레임워크의 AOP 개념.
STS 에서 웹 서버 설치 방법.
권효중 iBATIS.NET & Spring.NET 권효중
제 18 장 (Oracle) 오라클에서 트랜잭션 지원
테이블 관리 테이블 생성,수정,삭제 데이터 입력 수정, 삭제 2010학년도 2학기.
.Net Web Application 2007 컴퓨터공학실험(Ⅰ)
Architecture.
Spring Introduction.
MIDP 네트워크 프로그래밍 ps lab 김윤경.
2. 아키텍처 상에서 Spring 프레임워크가 차지하는 위치
10주 MariaDB에서 트랜잭션 지원 및 동시성 제어 기능
Mariadb 트랜잭션과 동시성 제어 장종원
 6장. SQL 쿼리.
임시테이블과 테이블변수 SQLWorld Study Group - 최명환 -.
6 객체.
Presentation transcript:

Spring 프레임워크의 이해 – day2 자바지기

첫째 날 둘째 날 셋째 날 개발 환경 세팅 Spring 기본 Spring MVC 사용자 관리 시스템 개발 (실습) Spring DI Spring AOP Spring JDBC & Transaction Spring Test

Spring은 Lightweight Application Framework

Spring Core : Spring 프레임워크의 근간이 되는 IoC(또는 DI) 기능을 지원하는 영역을 담당하고 있다 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을 지원하는 기능이다 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를 제공하고 있다.

첫째 날 둘째 날 셋째 날 개발 환경 세팅 Spring 기본 Spring MVC 사용자 관리 시스템 개발 (실습) Spring DI Spring AOP Spring JDBC & Transaction Spring Test

Spring DI

Inversion of Control? Dependency Injection?

요구사항 하나의 Interface 기반하에서 “Hello World!”와 “Hi World!” 메시지를 출력해야 한다. 출력하는 메시지를 생성하는 부분과 생성된 메시지를 Rendering하는 부분이 분리되어야 한다.

요구사항 변경 “Hello World!”와 “Hi World!!” 메시지외에 “안녕 World!”를 출력해야 한다. 출력하는 메시지를 생성하는 부분과 생성된 메시지를 Rendering하는 부분이 분리되어야 한다. 생성된 메시지를 단순히 출력하는 기능과 인자로 전달된 “Name”을 더하여 가공한 메시지를 출력해야 한다.

Factory Pattern

Factory Pattern

Spring

요구사항 전달하는 메시지가 “How”이면 “How are you?”를 출력한다. 전달하는 메시지가 “What”이면 “What’s your name?”를 출력한다. 전달하는 메시지가 “How”또는 “What”이 아니면 IllegalArgumentException을 Throw한다.

How?

(ApplicationContext) 클래스 의존관계에 대한 Metadata (XML 또는 Property) Spring Framework (ApplicationContext)

Inversion of Control (IoC)

DP IoC Setter Inj DI Constructor Inj Method Inj IoC : Inversion of Control DI : Dependency Injection DP : Dependency Pull EJB Spring DP IoC Setter Inj DI Constructor Inj Spring PicoContainer Method Inj

Servlet Container Servlet A Servlet B Servlet C Servlet D Service Init Create Destory Servlet Container Servlet A Servlet B Servlet C Servlet D

EJB Container EJB A EJB B EJB C EJB D Service Init Create Destory

IoC(DI) Container POJO A POJO B POJO C POJO D Service Init Create Destory IoC(또는 DI) Container POJO A POJO B POJO C POJO D

Spring Bean Scope

Singleton?, Non Singleton?

Singleton Pattern을 활용한 Singleton

지금까지의 Singleton 구현 방법 public class MessageService { private static MessageService instance; private MessageService() {} public static MessageService getInstance() { if(instance == null ) { instance = new MessageService(); } return instance;

Spring 기반하의 Singleton

Spring 프레임워크의 Singleton 구현 방법 <bean id="annyoungWorldMessageProvider" class="net.javajigi.ioc.AnnyoungWorldMessageProvider" scope=“singleton” /> <bean id="helloWorldMessageProvider" class="net.javajigi.ioc.HelloworldMessageProvider"/>

<bean id="renderer" class="net. javajigi. ioc <bean id="renderer" class="net.javajigi.ioc.DefaultMessageRenderer"> <property name="messageProvider"> <ref local=“hiWorldMessageProvider" /> </property> </bean> <bean id="hiWorldMessageProvider" class="net.javajigi.ioc.HiworldMessageProvider" /> ApplicationContext 키(key) 값(value) “renderer " DefaultMessageRenderer 인스턴스 " hiWorldMessageProvider” HiWorldMessageProvider 인스턴스

웹 애플리케이션 ServletContext(sigle instance) JVM 키(key) 값(value) “org.springframework.web.context. WebApplicationContext.ROOT" WebApplicationContext 인스턴스 JVM

Spring 프레임워크의 Non Singleton 구현 방법 <bean id="annyoungWorldMessageProvider" class="net.javajigi.ioc.AnnyoungWorldMessageProvider" scope=“prototype” /> <bean id="helloWorldMessageProvider" class="net.javajigi.ioc.HelloworldMessageProvider“

Singleton 인스턴스를 사용해야 할 때

Singleton Instance Thread A Thread B name = null public class Person { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; new Person(); Thread A new Person(); Thread B

person.setName(“예은”); Singleton Instance name = “예은” public class Person { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; person.setName(“예은”); Thread A

person.setName(“주한”); Singleton Instance name = “주한” public class Person { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; person.setName(“주한”); Thread B

person.getName(); => 주한 Singleton Instance name = “주한” public class Person { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; person.getName(); => 주한 Thread A

Static을 사용한 Singleton의 문제점 Dependency가 높아진다. Singleton 클래스마다 서로 다른 Configuration 가질 수 있다. interface-unfriendly => Test의 어려움. 상속하기 힘들다. Runtime시에 Singleton의 상태를 변경할 수 없다. OOP적으로 개발하는데 한계가 있다.

Spring Bean Instance 생성

new  <bean id="messageProvider" class="net.javajigi.di.NewMessageProvider"/>

<bean id="messageProvider" Factory method <bean id="messageProvider" class="net.javajigi.di.SingletonMessageProvider" factory-method="getInstance" />

FactoryBean Interface <bean id="messageProvider" class="net.javajigi.di.MessageProviderFactoryBean"> <property name="type"> <util:constant static-field="net.javajigi.di.MessageProviderFactoryBean.ANNYOUNG_WORLD_PROVIDER"/> </property> </bean>

<bean id="userService" class="net. javajigi. user. service  <bean id="userService" class="net.javajigi.user.service.UserServiceImpl"> <property name="userDAO"> <ref local="userDAO" /> </property> </bean> ApplicationContext context = new ClassPathXmlApplicationContext(paths); UserService userService = context.getBean(“userService”);

<bean id="userService" class="org. springframework. aop. framework <bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref local="userServiceTarget" /> </property> <property name="interceptorNames"> <list> <value>loggingAdvice</value> <value>emailNotificationThrowsAdvice</value> </list> </bean> ApplicationContext context = new ClassPathXmlApplicationContext(paths); ProxyFactoryBean factoryBean = context.getBean(“userService”);

<bean id="userService" class="org. springframework. aop. framework <bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref local="userServiceTarget" /> </property> <property name="interceptorNames"> <list> <value>loggingAdvice</value> <value>emailNotificationThrowsAdvice</value> </list> </bean> ApplicationContext context = new ClassPathXmlApplicationContext(paths); UserService userService = context.getBean(“userService”);

첫째 날 둘째 날 셋째 날 개발 환경 세팅 Spring 기본 Spring MVC 사용자 관리 시스템 개발 (실습) Spring DI Spring AOP Spring JDBC & Transaction Spring Test

Spring JDBC

Spring JDBC를 이용할 때 개발자들이 구현할 부분 작업 Spring JDBC 개발자 Connection 관리 O X SQL Statement 관리 ResultSet 관리 Row 데이터 추출 패러미터 선언 패러미터 Setting 트랜잭션 관리

Template Method Pattern

public abstract class AbstractClass { public void templateMethod() { // .. 비지니스 로직 구현 operation1(); operation2(); } protected abstract void operation1(); protected abstract void operation2();

public class ConcreteClassA extends AbstractClass { protected void operation1() { // TODO Auto-generated method stub } protected void operation2() {

Template Method = IoC

Callback Class Callback Method

public interface RowCallbackHandler { void processRow(ResultSet rs) throws SQLException; }

public void query(String sql, RowCallbackHandler callbackHandler) throws JdbcSqlException { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con = <code to get connection> ps = con.prepareStatement (sql); rs = ps.executeQuery(); while (rs.next()) { callbackHandler.processRow(rs); } rs.close(); ps.close(); } catch (SQLException ex) { throw new JdbcSqlException("Couldn't run query [" + sql + "]", ex); finally { DataSourceUtils.closeConnectionIfNecessary(this.dataSource, con);

class StringHandler implements JdbcTemplate.RowCallbackHandler { private List 1 = new LinkedList(); public void processRow(ResultSet rs)throws SQLException { 1.add(rs.getString(1)); } public String[] getStrings() { return (String[]) 1.toArray(new String[1.size()]); StringHandler sh = new StringHandler(); jdbcTemplate.query("SELECT FORENAME FROM CUSTMR", sh); String[] forenames = sh.getStrings();

Spring Transaction

Where? Persistence Layer Business Layer

TXa TXa TXa

TXa TXa TXa TXa TXb TXb

격리 레벨(Isolation Level) 상세 설명 TransactionDefinition.ISOLATION_DEFAULT 개별적인 PlatformTransactionManager를 위한 디폴트 격리레벨 TransactionDefinition.ISOLATION_READ_UNCOMMITTED 격리레벨중 가장 낮은 격리 레벨이다. 이 격리레벨은 다른 Commit되지 않은 트랜잭션에 의해 변경된 데이터를 볼 수 있기 때문에 거의 트랜잭션의 기능을 수행하지 않는다. TransactionDefinition.ISOLATION_READ_COMMITTED 대개의 데이터베이스에서의 디폴트로 지원하는 격리 레벨이다. 이 격리 레벨은 다른 트랜잭션에 의해 Commit되지 않은 데이터는 다른 트랜잭션에서 볼 수 없도록 한다. 그러나 개발자들은 다른 트랜잭션에 의해 입력되거나 수정된 데이터는 조회할 수는 있다. TransactionDefinition.ISOLATION_REPEATABLE_READ ISOLATION_READ_COMMITED 보다는 다소 조금 더 엄격한 격리레벨이다. 이 격리레벨은 다른 트랜잭션이 새로운 데이터를 입력했다면, 새롭게 입력된 데이터를 조회할 수 있다는 것을 의미한다. TransactionDefinition.ISOLATION_SERIALIZABLE 가장 많은 비용이 들지만 실뢰할만한 격리레벨을 제공하는 것이 가능하다. 이 격리레벨은 하나의 트랜잭션이 완료된 후에 다른 트랜잭션이 실행하는 것처럼 지원한다.

TXa TXb

? TXa TXb TXa SELECT CATEGORYNAME FROM ORDER WHERE ORDERID = 1 “BOOK” Result “BOOK” UPDATE ORDER SET CATEGORYNAME=“MUSIC” WHERE ORDERID = 1 TXb TXa SELECT CATEGORYNAME FROM ORDER WHERE ORDERID = 1 Result ?

Dirty Read TXa SELECT CATEGORYNAME FROM ORDER WHERE ORDERID = 1 Result “BOOK” UPDATE ORDER SET CATEGORYNAME=“MUSIC” WHERE ORDERID = 1 TXb TXa SELECT CATEGORYNAME FROM ORDER WHERE ORDERID = 1 Result “MUSIC”

NonRepeatable Read(Fuzzy Read) – Update, Delete TXa SELECT CATEGORYNAME FROM ORDER WHERE ORDERID = 1 Result “BOOK” UPDATE ORDER SET CATEGORYNAME=“MUSIC” WHERE ORDERID = 1 TXb TXa SELECT CATEGORYNAME FROM ORDER WHERE ORDERID = 1 Result “BOOK”

NonRepeatable Read(Fuzzy Read) – Update, Delete Commit TXb TXa SELECT CATEGORYNAME FROM ORDER WHERE ORDERID = 1 Result “MUSIC”

Phantom Read - Insert TXa TXb TXa SELECT COUNT(*) FROM ORDER Result 10 INSERT INTO ORDER (ORDERID, CATEGORYNAME) VALUES ( 11, “GAME” TXb TXa SELECT COUNT(*) FROM ORDER Result 10

Phantom Read - Insert TXb TXa Commit TXb TXa SELECT COUNT(*) FROM ORDER Result 11

Isolation Level Dirty Read NonRepetable Read Phantom Read Read uncommitted (ISOLATION_READ_UNCOMMITTED) Possible Read committed (ISOLATION_READ_COMMITTED) Not Possible Repetable read (ISOLATION_REPEATABLE_READ) Serializable (ISOLATION_SERIALIZABLE)

전달 행위(Propagation Behavior) 상세설명 TransactionDefinition.PROPAGATION_REQUIRED 이미 하나의 트랜잭션이 존재한다면 그 트랜잭션을 지원하고, 트랜잭션이 없다면, 새로운 트랜잭션을 시작한다. TransactionDefinition.PROPAGATION_SUPPORTS 이미 트랜잭션이 존재한다면 그 트랜잭션을 지원하고, 트랜잭션이 없다면 비-트랜잭션 형태로 수행한다. TransactionDefinition.PROPAGATION_MANDATORY 이미 트랜잭션이 존재한다면 그 트랜잭션을 지원하고 활성화된 트랜잭션이 없다면 예외를 던진다. TransactionDefinition.PROPAGATION_REQUIRES_NEW 언제나 새로운 트랜잭션을 시작한다. 이미 활성화된 트랜잭션이 있다면, 일시정지한다. TransactionDefinition.PROPAGATION_NOT_SUPPORTED 활성화된 트랜잭션을 가진 수행을 지원하지 않는다. 언제나 비-트랜잭션적으로 수행하고 존재하는 트랜잭션은 일시정지한다. TransactionDefinition.PROPAGATION_NEVER 활성화된 트랜잭션이 존재하더라도 비-트랜잭션적으로 수행한다. 활성화된 트랜잭션이 존재한다면 예외를 던진다. TransactionDefinition.PROPAGATION_NESTED 활성화된 트랜잭션이 존재한다면 내포된 트랜잭션으로 수행된다. 작업수행은 TransactionDefinition.PROPAGATION_REQUIRED으로 셋팅된것처럼 수행된다.

PROPAGATION_REQUIRED PROPAGATION_REQUIRED TXa TXa TXa TXa PROPAGATION_REQUIRED

PROPAGATION_REQUIRED PROPAGATION_REQUIRES_NEW TXa TXa TXb TXb PROPAGATION_REQUIRES_NEW

PROPAGATION_REQUIRED PROPAGATION_SUPPORTS TXa TXa TXa TXa PROPAGATION_SUPPORTS

PROPAGATION_SUPPORTS

PROPAGATION_REQUIRED PROPAGATION_NOT_SUPPORTED TXa TXa PROPAGATION_NOT_SUPPORTED

PROPAGATION_REQUIRED PROPAGATION_MADATORY TXa TXa TXa TXa PROPAGATION_MADATORY

PROPAGATION_MADATORY Throw Exception PROPAGATION_MADATORY

PROPAGATION_REQUIRED TXa TXa Throw Exception PROPAGATION_NEVER

전달 행위 : 필수 값으로서 Spring 프레임워크 전달행위 중의 하나를 사용할 수 있다. (필수) readOnly 유무 (선택) PROPAGATION, ISOLATION, readOnly, -Exceptions, +Exceptions 격리 레벨 (선택) Rollback 규칙 (선택) 전달 행위 : 필수 값으로서 Spring 프레임워크 전달행위 중의 하나를 사용할 수 있다. 격리 레벨 : 선택 값으로 Spring 프레임워크 격리 레벨 중의 하나를 사용할 수 있다. readOnly : 선택 값으로 실행하는 트랜잭션이 읽기 전용일 경우에 사용가능하다. 일반적으로 트랜잭션 내에서 SELECT 쿼리만을 실행하는 경우에 이 속성을 사용한다. Rollback 규칙 : Spring 프레임워크 트랜잭션의 디폴트 설정은 RuntimeException이 발생할 경우에는 Rollback, CheckedException이 발생하는 경우에는 Commit되도록 하고 있다. 그러나 트랜잭션의 속성을 지정할 때 Rollback 규칙을 이용하여 디폴트 설정을 변경하는 것이 가능하다. [그림 5-2]의 Rollback 규칙에서 마이너스(-)로 시작하는 Exception에 대해서는 무조건 Rollback, 플러스(+)로 시작하는 Exception은 무조건 Commit되도록 규칙을 변경할 수 있다.

PROPAGATION_REQUIRED, readOnly, timeout_0180, -ApplicationException

첫째 날 둘째 날 셋째 날 개발 환경 세팅 Spring 기본 Spring MVC 사용자 관리 시스템 개발 (실습) Spring DI Spring AOP Spring JDBC & Transaction Spring Test

학습 목표 기존 테스트 방식의 문제점 Spring 프레임워크에서 제시하는 해결 방법은?

컨테이너 기반 테스트 Cycle Test Development Server 재시작 Build Deploy

컨테이너 기반 테스트 Cycle의 문제점 한 Cycle에 소요되는 시간이 너무 길다. 최소 1분에서 5분 테스트를 자동화하기 힘들다.

Junit 기반 테스트 Cycle Test Development

org.springframework.test

기존의 테스트 방식 public class StandardOutMessageRendererTest { private MessageRenderer renderer; @Before public void setUp() throws Exception { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "net/javajigi/helloworld/HelloWorld.xml"); renderer = (MessageRenderer) applicationContext.getBean("renderer"); } @Test public void testRender() { renderer.render();

AbstractDependencyInjectionSpringContextTests public class StandardOutMessageRendererWithDITest extends AbstractDependencyInjectionSpringContextTests { private MessageRenderer renderer; public void setRenderer(MessageRenderer renderer) { this.renderer = renderer; } @Override protected String[] getConfigLocations() { return new String[] { "classpath:net/javajigi/helloworld/HelloWorld.xml" }; public void testRender() { renderer.render();

테스트를 자동화할 수 없다. 데이터베이스 테스트의 문제점 테스트시 같은 데이터를 추가할 경우 Duplicate Exception 발생. 데이터의 상태를 변경으로 인해 반복 테스트가 힘들다. 테스트를 위한 쓰레기 데이터가 쌓인다. 테스트를 자동화할 수 없다.

테스트를 위해 추가적인 작업이 필요함 개발 생산성 저하 지금까지의 해결방법 테스트 종료시 추가한 데이터를 삭제한다. 테스트 종료시 이전 상태로 원복한다. 테스트를 위해 추가적인 작업이 필요함 개발 생산성 저하

테스트시 변경된 데이터를 자동 Rollback AbstractTransactionalSpringContextTests 테스트시 변경된 데이터를 자동 Rollback

beginTx Tx Business Logic Success 예 Commit 아니오 Rollback

beginTx Tx Unit Test Default 자동 Rollback

AbstractTransactionalDataSourceSpringContextTests 테스트를 위한 Query 구현이 가능

Spring Mock Object Mock Object ?

MockHttpServletRequest MockHttpServletResponse

Thank you.