아키텍트가 바라보는
Spring Framework
㈜이밸리사람들
컨설팅 사업부
이해일 이사
차례
기본기
컨테이너
쓰레드
Spring 적용하기
Patten
Aspect
컨테이너
컨테이너
동작 환경
컨테이너
컨테이너
Java EE
웹 어플리케이션
비즈니스
어플리케이션
엔터프라이즈
어플리케이션
컨테이너
Java EE - EJB
컨테이너
JavaEE - Spring
컨테이너
컨테이너에 넣을 구현체는 무엇인가?
컨테이너가 제공할 동작 환경은 무엇인가?
CMT
Thread Safety
Component Life Cycle
쓰레드
도전
쓰레드
해법
쓰레드
동시성 문제
Thread1 Heap
Stack
Thread2
Stack
Object A
attribute
쓰레드
동시성 문제 – 왜?
JMM
쓰레드
동시성 문제 - 동기화
주 메모리
object
a := 2
lock
Thread 1
바이트 코드
실행 엔진
작업 메모리
a := 2
1. 작업
메모리에
복사한다.
Thread
바이트 코드
실행 엔진
작업 메모리
a := 1
주 메모리
object
a := 1
lock
Thread1
바이트 코드
실행 엔진
작업 메모리
a := 1
주 메모리
object
a := 2
Thread 2
바이트 코드
실행 엔진
lock
2. a를
읽어서
값을
바꾼다.
1. 작업
메모리에
복사한다.
Thread 2
바이트 코드
실행 엔진
작업 메모리
a := 1
작업 메모리
a := 2
if (a > 0)
{
a--;
}
주메모리 Object 내용
2. a를
읽어서
값을
바꾼다.
3. 쓰레드
종료시점
에 동기화
주 메모리
object
a := 1
lock
Thread 2
바이트 코드
실행 엔진
작업 메모리
a := 1
3. 쓰레드
종료시점
에 동기화
쓰레드
동시성 문제
심각성
일반 개발 환경인 단일 프로세서 환경에서는 잘 드러나지 않는다.
다중 프로세서가 장착된 운영 환경에 가서야 드러나는 경우가 많다.
부하가 적을 때는 드러나지 않기 때문에 재현하기 쉽지 않다.
해결하기 아주 힘든
문제가 된다.
쓰레드
동시성 문제 - 사례
public void put(Object values)
{
int count = 1;
while (true)
{
if ( )
{
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
MsgParameter msp = new MsgParameter();
msp.add(poolType);
throw new FWRuntimeException(FWExceptionCode.EX00075, msp, e);
}
count++;
// 객체풀이 여유가 없을 경우 최대 시도 횟수만큼 재시도하고
// 재시도 후에도 여유가 없을 경우는 풀의 맨처음 객체를 제거한다.
if (count == retryCount)
{
if(this.objPool.size()>0)
{
this.objPool.remove(0);
}
}
continue;
}
this.objPool.add(values);
break;
}
}
쓰레드
쓰레드 안정성을 보장하라.
JVM 차원 필드 동기화 : volatile – 정확히 동작하지 않음
코드 차원 동기화 : synchronized – 동시성 VS 정합성
객체 공유하지 않기 : 참조 넘기지 않기
불변 객체 만들기 : singleton
쓰레드
synchronized
synchronized로 구분된 블락은 특정 시점에 오직 한 쓰레드만 실
행할 수 있다.
주메모리와 작업메모리 내용을 동기화해서 한 쓰레드가 바꾼 상
태를 다른 쓰레드가 알아차리게 한다.
Oracle select … for update와 비슷하다.
쓰레드
synchronized
쓰레드
Synchronized
동기화는 성능을 크게 저하시킨다. 꼭 필요할 때만 동기화하라.
final public class ServiceLocator
{
private Context ctx;
private static ServiceLocator SINGLETON;
private ServiceLocator()
{
this.ctx = new InitialContext();
…
}
public static synchronized ServiceLocator getInstance()
{
if (SINGLETON == null)
{
SINGLETON = new ServiceLocator();
}
return SINGLETON;
}
…
}
동기화가 필요할까?
[YES] 객체가 한 번만 생성된다는
것을 보장하려면 동기화는 필요하다.
[NO] 아주 빈번하게 호출되는
메소드를 동기화하면 전체 시스템
성능에 영향을 준다.
쓰레드
Synchronized
동기화는 성능을 크게 저하시킨다. 꼭 필요할 때만 동기화하라.
쓰레드
JavaEE - 서블릿
Web Server
WAS
Client
Client
Client
Servlet
Thread
Thread
Thread
쓰레드
JavaEE - 서블릿
단일 쓰레드 서블릿 – 동시성 저하
쓰레드
JavaEE - EJB
Application Server
WAS
Client
Client
Client
Thread
Thread
Thread
EJB
EJB
EJB
쓰레드
JavaEE 안정성 문제
WAS
Client
Client
Client
Thread
Thread
Thread
Servlet
object
object
쓰레드
JavaEE 안정성 문제
WAS
Client
Client
Thread EJB 1
Thread EJB 3
EJB 2
object
object
object
쓰레드
JavaEE - Spring
Spring 적용하기
컨테이너에 넣을 구현체는 무엇인가?
EJB
Home/Business Interface, Bean Class, DD
Core J2EE Pattern, EJB Pattern 참조하여 컨테이너에 넣을
Spring
Interface, Bean, Context File
Pattern???
Spring 적용하기
Pattern
HTTP 기반 요청에 Spring MVC 이용
- 트랜잭션/기본 디버그 로깅/프로파일링 애스팩트화
- 비즈니스 컴포넌트 구성요소 가운데 퍼서드와 자원
접근객체를 Bean으로 등록
Spring 적용하기
Pattern
Spring Beans
singleton
Spring Beans
singleton
new로 생성
new로 생성
Spring 적용하기
Pattern
트랜잭션 전파
Spring 적용하기
Pattern
실행시점 객체 다이어그램
DTO를 제외한 모든 객체는 상태가 없다.
스프링 빈은 모두 singleton scope를 가진다.
모든 클래스는 인스턴스를 하나만 만들어 낸다.
Spring 적용하기
Aspect
Spring 적용하기
Aspect
트랜잭션

아키텍트가 바라보는 Spring framework