-
토비의 스프링[8] 스프링이란 무엇일까?Spring 2021. 7. 19. 11:08
스프링 프레임워크
자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크
애플리케이션의 전 영역을 관통하는 일관된 프로그래밍 모델과 핵심 기술을 바탕으로 해서 각 분야의 특성에 맞는 필요를 채워주고 있기 때문에, 애플리케이션을 빠르고 효과적으로 개발할 수가 있다. 이것이 스프링이 애플리케이션 프레임워크라 불리는 이유다.스프링을 MVC프레임워크 혹은 JDBC/ORM 지원 프레임워크라고 생각하는 것은 스프링이 다루는 일부 영역만 봤기 때문이다.
스프링을 IoC/DI 프레임워크나 AOP 툴이라고 보는 이유는 스프링이 제공하는 핵심 기술에만 주목했기 때문이다.
스프링의 일차적인 존재 목적은 핵심 기술에 담긴 프로그래밍 모델을 일관되게 적용해서 엔터프라이즈 애플리케이션 전 계층과 전 영역에 전략과 기능을 제공해줌으로써 애플리케이션을 편리하게 개발하게 해주는 애플리케이션 프레임워크로 사용된다.경량급
스프링이 경량급이라는 의미는 가볍고 작은 규모의 코드로 이루어져 있는 이유가 아니다. (오히려 코드도 많고 복잡)
이는 EJB 같은 과도한 엔지니어링이 적용된 기술과 대비시켜 설명하기에 사용된 표현이다. 과거 과도한 욕심으로 인하여 개발환경 운영서버, 테스트과정 개발, 빌드, 작성된 코드를 매우 무겁게 만든 EJB에 비하여 가볍다는 의미이다.
또한 스프링의 경량급이라는 의미로 같은 기능을 수행하는 코드인데도 스프링의 코드가 가벼운 이유는 다른 불필요하게 등장한 코드, 프레임워크와 서버환경에 의존적인 부분을 제거해주기 때문이다.자바 엔터프라이즈 개발을 편하게 하기위하여 EJB가 등장했다.
EJB를 사용하면 애플리케이션의 로우레벨의 트랜잭션, 상태, 멀티스레딩, 리소스 풀링과 같은 복잡한 로우레벨 API를 몰라도 쉽게 애플리케이션을 개발할 수 있습니다.
하지만 이는 기대와 다르게 더 큰 복잡도를 불러오게 되었고 결국 다른 대안을 찾게 되던 도중 나온게 스프링이다. 스프링은 EJB가 이루려는 궁극의 목적을 제대로 실현하게 해주는 프레임 워크이다.오픈소스
스프링은 오픈소스 프로젝트 방식으로 개발돼왔다.
장점으로는 커뮤니티 공간 안에서 투명한 방식으로 참여를 통해 개발되기에 매우 빠르고 유연한 개발이 가능하다. 그렇기에 사용자 입장에서는 라이선스 비용에 대한 부담이 없다.
단점으로는 지속적이고 안정적인 개발이 가능할지가 불투명하다. 개발자의 여가시간을 이용해 일종의 취미로 만들어질 가능성이 높기에 문제가 생긴다면 그 즉시 중단될 수 있다.
보완으로는 스프링에 대한 전문적인 기술지원과 컨설팅 그리고 기반으로 개발된 시스템을 안정적으로 운영할 수 있도록 사용 제품을 통해 수익을 얻고하여 이를 중점적으로 하는 유겐 횔러와 자바 엔터프라이즈 세계에서 손꼽히는 최상급 개발자들이 주축이 돼서 만든 회사가 존재한다.POJO 프로그래밍
이 책에서 핵심 개발자들은 스프링의 정수는 인터프라이즈 서비스 기능을 POJO에 제공하는 것이라고 했다. 엔터프라이즈 서비스는 보안, 트랜잭션과 같은 엔터프라이즈 시스템에서 요구되는 기술을 말한다. 즉 엔터프라이즈 서비스 기술과 POJO라는 애플리케이션 로직을 담은 코드를 분리했다는 뜻이기도 한다. 분리됐지만 반드시 필요한 엔터프라이즈 서비스 기술을 POJO 방식으로 개발된 애플리케이션핵심 로직을 담은 코드에 제공한다는 것이 스프링의 가장 강력한 특징과 목표다.
스프링의 중 기술인 IoC/DI, AOP와 PSA는 애플리케이션을 POJO로 개발할 수 있게 해주는 가능기술이라고 불린다.
POJO의 조건
특정 규약에 종속되지 않는다.
- POJO는 자바 언어와 꼭 필요한 API 외에는 종속되지 않아야 한다.
특정 환경에 종속되지 않는다. - 순수한 애플리케이션 로직을 담고 있는 오브젝트 코드가 특정 환경에 종속되어 있다면 그것 역시 POJO가 아니다. POJO는 환경에 독립적이어야 한다.
- 비즈니스 로직을 담은 코드에 HttpServletRequest나 HttpSession 캐시와 관련된 API가 등장하거나 웹 프레임워크의 클래스를 직접 이용하는 부분이 존재한다면 그것은 진정한 POJO라 볼 수 없다.
- 애노티에션이 단지 코드로 표현하기는 적절치 않은 부가적인 정보를 담고 있고, 그 때문에 환경에 종속되지만 않는다면 여전히 POJO라고 할 수 있다. 하지만 종속적인 저보를 담고 있다면 그때는 POJO로서의 가치를 잃어버린다고 할 수 있다.
- 단지 자바의 문법을 지키고, 순수하게 JavaSE API만을 사용했다고 해서 그 코드를 POJO라고 할 수 는 없다. POJO는 객체지향적인 자바 언어의 기본에 충실하게 만들어져야 하기 때문이다.
POJO의 장점
- 특정한 기술과 현광에 종속되지 않는 오브젝트는 그만큼 깔끔한 코드가 될 수 있다.
- 로우레벨의 기술과 환경에 종속적인 코드가 비즈니스 로직에 섞여나오는 만큼 코드가 지저분해 읽고 이해하기 어려우며, 검증 테스트 작성에 한계가 있다.
- POJO로 개발된 코드는 자동화된 테스트에 매우 유리하다
- 환경의 제약은 코드의 자동화된 테스트를 어렵게 한다. 반면 종속되지 않은 POJO 코드는 매우 유연한 방식으로 원하는 레벨에서 코드를 빠르고 명확하게 테스트할 수 있다.
- 객체지향적인 설계를 자유롭게 적용할 수 있다.
- 개발자들이 자바와 객체지향 프로그래밍, 모델링과 설계에 대한 배운 도메일 모델과, 디자인 패턴 등은 POJO가 아니고는 적용하기 힘들다.
POJO 프레임워크
스프링을 이용하면 POJO 프로그래밍의 장점을 그대로 살려 엔터프라이즈 애플리케이션 핵심 로직을 객체지향적인 POJO를 기반으로 깔끔하게 구현하고, 동시에 엔터프라이즈 환경의 각종 서비스와 기술적인 필요를 POJO 방식으로 만들어진 코드에 적용할 수 있다.
스프링은 비즈니스 로직의 복잡함과 엔터프라이즈 기술의 복잡함을 분리해서 구성할 수 있게 해주며, 자신은 기술영역에만 관여하고 비즈니스 로직을 담당하는 POJO에서는 모습을 감춘다. 즉 POJO 프레임워크로서 스프링은 자신을 직접 노출시키지 않으면서 애플리케이션을 POJO로 쉽게 개발할 수 있게 해준다.스프링의 기술
- 제어의 역전 / 의존관계 주입
유연한 확장이라는 장점은 OCP의 확장에는 열려 있다에 해당한다. DI는 역시 OCP의 "변경에는 닫혀있다"라는 말로도 설명이 가능하다. 폐쇄 관점에서 볼 때 장점은 재사용이 가능하다라고 볼 수 있다.
A -> B(A가 B를 의존) 라는 의존관계 속에서 B는 확장이 되어도 A는 영향을 받지 않기에 B관점에서는 유연한 확장이고 A관점으로 보면 변경 없이 재사용이 가능하다고 볼 수 있다. (B의 구현 방법이 변경되어도 상관없음)
DI 활용 방법
- 핵심기능의 변경
- 서비스 오브젝트가 사용하는 DAO의 구현을 JPA -> MyBatis -> JDO 등 자유롭게 구현 방식을 바꾸는 것
- 핵심기능의 동적인 변경
- DI도 기본적으로 런타임 시에 동적으로 의존 오브젝트를 연결해주는 것이지만 DI 이후에는 변경되지 않는다. 이를 이용하여 DAO -> DataSource(dao가 datasource를 의존)구조에서 하나의 DAO를 여러개의 DataSource를 의존하게 하여 현재 로그인한 계정의 정보에 따라 그때그때 다른 DataSource를 DAO가 사용하게 할 수 있다. (VIP는 좀더 빠른 속도로 DB를 처리하기 위함)
- 부가기능 추가
- 인터페이스를 이용하여 실제 사용 오브젝트는 외부에서 주입하는 DI를 적용 하면 데코레이터 패넡을 쉽게 적용할 수 있다.
- 핵심기능 및 클라이언트 코드에 영향을 주지 않으면서 부가기능 추가
- 인터페이스를 이용하여 실제 사용 오브젝트는 외부에서 주입하는 DI를 적용 하면 데코레이터 패넡을 쉽게 적용할 수 있다.
- 인터페이스의 변경
- A가 C오브젝트를 사용하려 하지만 A는 B인터페이스를 사용하도록 만들어졌있고 C는 B인터페이스를 구현하지 않았다. 이때 A가 DI를 통해 B의 구현 오브젝트를 받도록 되있다면 B인터페이스를 구현했으면서 내부에서 C를 호출해주는 기능을 가진 어댑터 오브젝트를 만들어 A에 DI해주면 된다.
- A->B(C로위임)->C처럼 구성되어 A는 DI덕분에 자신의 코드를 수정하지 않아도 된다.
- A가 C오브젝트를 사용하려 하지만 A는 B인터페이스를 사용하도록 만들어졌있고 C는 B인터페이스를 구현하지 않았다. 이때 A가 DI를 통해 B의 구현 오브젝트를 받도록 되있다면 B인터페이스를 구현했으면서 내부에서 C를 호출해주는 기능을 가진 어댑터 오브젝트를 만들어 A에 DI해주면 된다.
- 프록시
- 필요한 시점에서 실제 사용할 오브젝트를 초기화하고 리소르를 준비해주는 지연된 로딩을 적용하려면 프록시가 필요하다. 원격 오브젝트를 호출할 때 마치 로컬에 존재하는 오브젝트처럼 사용하는 원격 프록시를 적용하려고 할 때도 프록시가 필요하며, 두 가지 모두 DI를 필요로 한다. 스프링은 EJB 원격 호출을 포함하여, REST, HTTP, 웹서비스, 등 다양한 리모팅 기술을 지원하며 마찬가지로 DI를 통해 이루어진다.
- 템플릿과 콜백
- 고정적인 작업 흐름과 그 사이에서 계속 변경되는 부분을 분리하여 만든 템플릿/콜백은 DI 원리를 응용해 적용하면 간결한 코드로 이용할 수 있다.
- 스프링은 20여가지 템플릿/콜백이 적용된 기능을 지원하며, 필요에 따라 DI원리에 따라 직접 응용할 수 있다.
- 고정적인 작업 흐름과 그 사이에서 계속 변경되는 부분을 분리하여 만든 템플릿/콜백은 DI 원리를 응용해 적용하면 간결한 코드로 이용할 수 있다.
- 싱글톤과 오브젝트 스코프
- DI가 필요한 중요한 이유 중 하나로 DI할 오브젝트의 라이프사이클을 제어할 수 있다. 라이프사이클을 DI 컨테이너가 주관하기에 그 오브젝트의 스코프를 자유롭게 제어할 수 있다.
- 테스트
- 여타 오브젝트와 협력해서 동작하는 오브젝트를 고립시켜다른 오브젝트와의 사이에서 일어나는 일을 테스트를 위해 조작할 수 있도록 만든다.
- 의존 오브젝트는 목, 스텁 오브젝트로 제작하여 대역으로 쓴다. (이때 DI를 통해 테스트용 객체에 의존성을 주입할 수 있다.)
- 여타 오브젝트와 협력해서 동작하는 오브젝트를 고립시켜다른 오브젝트와의 사이에서 일어나는 일을 테스트를 위해 조작할 수 있도록 만든다.
AOP
IoC/DI를 이용해서 POJO에 선언적인 엔터프라이즈 서비스를 제공할 수 있지만 일부 서비스는 순수한 객체지향 기법으로는 POJO의 조건을 유지한 채로 적용하기 힘들다. 바로 이런 문제를 해결하기 위해 AOP가 필요하다.
AOP를 자바에 적용하는 기법은 크게 2가지로 나뉜다.스프링과 같이 다이내믹 프록시를 사용하는 방법
- 기존 코드에 영향을 주지 않고 부가기능을 적용하게 해주는 데코레이터 패턴을 응용한 것이다. 대신 부가기능을 부여할 수 있는 곳은 메소드의 호출이 일어나는 지점뿐이라는 제약도 있다. 인터페이스와 DI를 활용하는 데코레이터 패턴이 기반원리이다. 부가기능을 구현한 코드나 기능을 적용할 대상을 찾는 방법 모두 평범한 자바 클래스로 만들면 된다.
- 스프링의 기본적인 AOP 구현 방법은 다이내믹 프록시를 이용하는 프록시 AOP 방식이다. 엔터프라이즈 개발에서 필요로 하는 AOP는 대부분 이 프록시 방식의 AOP면 된다.
- 기존 코드에 영향을 주지 않고 부가기능을 적용하게 해주는 데코레이터 패턴을 응용한 것이다. 대신 부가기능을 부여할 수 있는 곳은 메소드의 호출이 일어나는 지점뿐이라는 제약도 있다. 인터페이스와 DI를 활용하는 데코레이터 패턴이 기반원리이다. 부가기능을 구현한 코드나 기능을 적용할 대상을 찾는 방법 모두 평범한 자바 클래스로 만들면 된다.
자바 언어의 한계를 넘어서는 언어의 확장을 이용하는 방법
- AspecJ를 이용하여 프록시 방식의 AOP에서는 불가능한 다양한 조인포인트를 제공한다. 이는 그만큼 사용하기 까다롭지만 경우에 따라 프록시 방식의 AOP로는 할 수 없는 작업을 위하여 AspectJ를 사용해야 한다.
AOP의 적용 단계
- 미리 준비된 AOP 이용
- 전담팀을 통한 정책 AOP 적용
- AOP의 자유로운 이용
PSA
환경과 세부 기술의 변화에 관계없이 일관된 방식으로 기술에 접근할 수 있게 해주는 PSA다. (POJO로 개발된 코드는 특정 환경에 종속되지 않아야 한다.)'Spring' 카테고리의 다른 글
Spring Security[2] (0) 2021.07.19 Spring Security[1] (0) 2021.07.19 토비의 스프링[7] 스프링 핵심기술과 응용 (0) 2021.04.14 토비의 스프링[6] AOP (0) 2021.03.08 토비의 스프링[5] 서비스 추상화 (0) 2021.02.25 - POJO는 자바 언어와 꼭 필요한 API 외에는 종속되지 않아야 한다.