Spring, 제대로 알고 가자

706__·2021년 2월 24일
0

Spring

목록 보기
1/3
post-thumbnail

Framework

프로그래밍에서 특정 운영 체제를 위한 응용 프로그램 표준 구조를 구현하는 ClassLibrary 모음

  • Library : 자주 사용되는 Logic을 재사용하기 편하도록 정리한 일련의 코드 뭉치
  • Class : 객체 Object를 정의하는 설계도
  • Field : 객체의 상태를 나타내며, 클래스의 구성단위
    • Class에 포함된 Variable
  • Method : 객체의 행동을 나타내며, 클래스의 구성단위
    • 특정 작업을 수행하기 위한 명령문의 집합

Spring Framework

Java Platform을 위한 Open Source Application Framework

EnterPrised Application을 개발하기 위한 모든 기능을 종합적으로 지원하는 경량화된 솔루션

  • 대규모의 Data Process / Transaction 이 동시에 여러 사용자로부터 행해지는 매우 큰 규모의 개발 환경
  • 즉, 개발에 대한 표준을 제공하는 틀

  • 동적인 웹 페이지를 개발하기 위한 여러 Service를 제공
  • Eclipse에 Plugin을 결합하며 확장성을 넓히고, Project 구조 개발 방식이 훨씬 유연
  • 기본적으로 Maven 환경을 지원하므로 Package 의존성 관리에 효율적
  • 자체적으로 Tomcat Server 제공

Spring Properties

LightWeight Container : 경량 컨테이너

  • Spring은 객체를 담고 있는 Container로서, Java 객체를 직접 관리한다.

Spring이 컨테이너라고?

결론부터 얘기하자면, 컨테이너란 사용자가 작성한 코드의 처리 과정을 위임받은 독립적인 존재이다.
즉, 컨테이너는 적절한 설정이 되어 있다면, 누구의 도움 없이도 작성된 코드를 스스로 참조한 뒤에, 자동으로 객체의 생성 / 소멸을 컨트롤해준다.

정확하게 말하자면, 프로그램을 이용하는 "사용자의 호출에 의해 컨테이너가 동작하는 구조" 를 의미한다.

WAS : Web Application Service 역시 컨테이너의 예이다.

Spring에서 제공하는 컨테이너는 2가지 유형이 있다.

  • BeanFactory
  • BeanFactory 를 상속하는 ApplictionContext

BeanFactory

Spring 설정 파일인 ApplicationContext.xml에 등록된 Bean 객체를 생성하고 관리하는 가장 기본적인 컨테이너 기능만 제공한다.

컨테이너가 구동될 때 객체를 생성하는 것이 아니라 Client로부터 요청이 있을 경우에만 객체를 생성하는 Lazy loading방식으로 동작한다.

ApplicationContext

이는 BeanFactory를 확장한 컨테이너이다. Transaction 관리Message 기반의 다국어 처리 등 다양한 기능이 추가적으로 지원된다.

컨테이너가 구동되는 시점에 Bean 에 등록되어 있는 Class들을 객체화하는 즉시 로딩 방식으로 동작한다.

대표적으로 이 ApplicationContext를 구현한 Class는 GenericXmlApplicationContext 이다.


  • Java 객체 생성 / 소멸과 같은 Life Cycle 을 관리하며, Spring으로부터 필요한 객체를 얻어올 수 있다.

POJO : Plain Old Java Object 방식의 Framework

  • 이상적으로, POJO 는 Java 언어 사양 외 어떠한 제한에도 묶이지 않는 Java Object라 할 수 있다.

왜 POJO를 지향해야 할까?

Spring Framework 이전의 경우, 원하는 EnterPrise 기술이 있다면, 직접적으로 사용하는 객체를 설계했다. 그러나 이러한 개발 방식으로 특정 기술 / 환경에 종속되어 의존하게 된 Java Code는 가독성이 떨어져 유지 보수에 어려움을 겪었다. 또한, 특정 기술의 Class를 상속 / 의존하게 되어 확장성 역시 매우 떨어지게 되었다. 다시 말하면, 객체지향의 성격을 띄는 Java가 객체지향 설계의 장점을 잃어버린 것이다.

즉, 본래 Java의 장점을 살릴 수 있는 오래된 방식의 순수한 Java 객체 개념이 등장하게 되었다.

특정 기술을 사용하고 싶다면?

Spring을 개발해본 사람들은 Hibernate를 접해본 적 있을 것이다. POJO의 정의에 따르면, 특정 기술에 종속되지 않아야 한다. Spring이 POJO를 유지하면서 Hibernate를 사용할 수 있는 이유는 무엇일까?

바로, Spring에서 정한 표준 Interface 때문이다. ORM이라는 기술을 사용하기 위해 JPA 표준 Interface를 정해두었다.

객체-관계 매핑 ORM : Object Relational Mapping

객체와 관계형 데이터베이스의 데이터를 자동으로 Mapping해주는 것을 말한다.

  • 객체 지향 프로그래밍은 Class 를 사용하고, 관계형 데이터베이스는 Table 을 사용한다.
  • 객체 모델과 관계형 모델 간에 불일치가 존재한다.
  • ORM 을 통해 객체 간의 관계를 바탕으로 SQL을 자동으로 생성하여 불일치를 해결한다.

  • 일반적인 JE22 Framework와 달리 구현을 위해 특정 Interface를 구현 / Class를 상속받을 필요가 없다.
  • 기존에 존재하던 Library 등을 지원하기에 용이하며, 객체가 가볍다.

제어 반전 IoC : Inversion Of Control 지원

  • Spring의 가장 중요하면서, 핵심적인 기능
  • 간단히 정리하면, 제어반전이란 대신 해줌이다❗️

IoC는 컨테이너이다

컨테이너는 우리가 작성한 코드의 컨트롤 - 즉, 객체의 생성과 소멸 - 을 대신 해준다.

IoC 역시, 언제 호출될지 모르는 코드를 마음껏 칠 수 있도록 한다.

그래서 IoC가 뭐라고?

IoC 제어 반전은 사용자가 작성한 프로그램이 재사용 라이브러리의 흐름 제어를 받게 되는 소프트웨어 디자인 패턴이다.

일반적인 프로그래밍에서, 흐름은 사용자가 작성한 프로그램이 외부의 라이브러리 코드를 호출함으로써 이용한다. 그렇지만 제어 반전의 경우, 외부 라이브러리의 코드가 사용자가 작성한 코드를 호출한다

  • 작업 구현 방식과 작업 수행 자체를 분리한다.
  • 다른 시스템이 어떻게 동작할지에 대해 고민할 필요 없이, 정해진 협약대로만 동작하게 하면 된다.
  • 모듈을 바꾸더라도 다른 시스템에 부작용을 일으키지 않는다

정리하면, IoC란 추상화 원칙 중 한 가지로, 실행에 필요한 객체의 생성 / 사용제어 권한을 Framework에게 위임함으로써, Client가 신경써야 할 부분을 줄이는 전략이다.

여기까지 이해가 되었다면, 의문이 생기는 것이 정상이다. 도대체! Framework가 나의 코드를 어떻게! 호출할 수 있을까?

제어 반전의 가장 쉬운 접근 방식은 Framework의 event, delegate에 나의 Method를 등록하는 것이다.

또 다른 접근 방식은 Framework에 정의되어 있는 Interface, Abstract 추상타입을 나의 Method에서 구현 / 상속한 뒤 넘겨주는 것이다. 이 방식은 객체를 Framework에게 주입하는 것이며, 뒤에서 설명할 의존성 주입이다.


  • Control 제어권이 사용자가 아닌 Framework에 있어, 필요에 따라 Spring에서 사용자 코드 호출

의존성 주입 DI : Dependency Injection 지원

  • Spring은 설정 파일을 통해 객체 간의 의존 관계를 설정할 수 있다.

Bean이란 무엇일까?

Spring에서 선언되어 관리되고 있는 InstanceBean 이라 부른다.

Spring에서 이와 같이 선언된 Bean의존성 주입 DI 방식으로 관리하고 있다.

의존성을 주입하는 방식은 다음과 같다.

  • xml 설정 파일
  • Class 내 Setter / Constructor
  • Annotation
    • @Autowired : Spring아, 이 Type에 맞는 것을 찾아서 이 친구랑 그 친구를 연결시켜줘!
    • @Component : Spring아, 이건 네가 관리해야 하는 Bean이야!

Spring Controller에 등록된 Bean을 사용하기 위해서는, Container에 등록된 Bean의 참조 값을 받아와서 사용한다.

Spring Controller 혹은 IoC Container에 등록된 Bean들은 개발자가 프로그램 실행 도중 변경 불가능하므로 일관성있는 Instance를 사용할 수 있게 된다.

그래서 DI를 왜 사용하는거야?

DI란 간단하게 표현하면, 미리 찜해둠으로 나타낼 수 있겠다. 웃기는 표현을 사용하자면, 마치 받아먹을 사람은 생각도 않는데, 먼저 말부터 꺼내놓는 파렴치한 코딩방식이다.

DI 방식으로 코드를 작성하게 되면, 현재 사용하고 있는 객체의 Method가 어떻게 작성되었는지, 그 Class가 기능을 잘 구현했는지조차도 알 필요가 없다.

그저, Class의 기능을 추상적으로 묶어둔 Interface만 갖다쓰면 된다. 나머지는 Spring에서 찜해놓은 걸 자동으로 연결시켜줄테니,,

빠른 이해를 돕기 위해, 다음의 예시를 살펴보자.

StrategyPatternService Class를 보면, 객체 sp는 Interface 객체인 StrategyPattern으로 선언되었으며, StrategyPattern의 Method인 dependency_injection()를 호출하였다.
즉, 객체 생성 과정에서 spStrategyPatternImpldependency_injection()라는 Method를 호출해버렸다는 것이다.

정리하면, DI 방식을 사용함으로써, Inteface의 Method만 이용하더라도 구현부는 나중에 주입을 통해 해결할 수 있으므로 획기적인 분업과 동시에 구현 Class를 쉽게 교체할 수 있다는 장점을 얻었다.


  • 그로 인해, 객체들간의 느슨한 결합을 유지하고, 직접 의존하고 있는 객체를 굳이 생성 / 검색할 필요성을 없앤다.
  • 각각의 계층 / 서비스들 간에 의존성이 존재할 경우, Framework가 연결시킨다.

관점 지향 프로그래밍 AOP Aspect-Oriented Programming 지원

  • AOP문제를 바라보는 관점을 기준으로 프로그래밍하는 기법이다.
  • 문제를 해결하기 위한 핵심 관심 사항전체에 적용되는 공통 관심 사항을 기준으로 프로그래밍함으로써, 공통 Module을 여러 코드에 쉽게 적용할 수 있도록 한다.

왜 AOP를 사용할까?

"관점 지향"이란 쉽게 말해, 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하는 것이다.

모듈화란, 어떤 공통된 로직이나 기능을 하나의 단위로 묶는 것을 말한다.

AOP에서 각 관점을 기준으로 로직을 모듈화한다는 것은 결국, 코드들을 부분적으로 나누어 모듈화한다는 의미이다. 이 때, 코드에서 다른 부분에 계속해서 반복해서 사용하는 코드를 발견할 수 있는데, 이것을 흩어진 관심사 Crosscutting Concerns 라고 부른다.

즉, 흩어진 관심사를 Aspect로 모듈화하고, 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는 것이 AOP의 취지이다.

AOP은 어떻게 사용해야할까?

Spring에서, 프록시 패턴 기반의 AOP 구현체, 프록시 객체를 사용하는 이유는 접근 제어 / 부가 기능을 추가하기 위해서이다.

AOPSpring Bean에만 적용 가능하며, 모든 AOP 기능을 제공하는 것이 아닌, Spring IoC와 연동하여 Enterprise Application 간에서 발생하는 흔한 문제에 대한 해결책을 지원하는 것이 주된 목적이다.

  • Aspect : 위에서 설명한 흩어진 관심사를 모듈화 한 것. 주로 부가기능을 모듈화함.
  • Target : Aspect를 적용하는 곳 (Class, Method .. )
  • Advice : 실질적으로 어떤 일을 해야할 지에 대한 것, 실질적인 부가기능을 담은 구현체
  • JointPoint : Advice가 적용될 위치, 끼어들 수 있는 지점. 메서드 진입 지점, 생성자 호출 시점, 필드에서 값을 꺼내올 때 등 다양한 시점에 적용가능
  • PointCut : JointPoint의 상세한 스펙을 정의한 것. 'A란 메서드의 진입 시점에 호출할 것'과 같이 더욱 구체적으로 Advice가 실행될 지점을 정할 수 있음

  • Transaction이나 Logging, Security와 같이 여러 Module에서 공통적으로 사용하는 기능의 경우, 분리하여 관리 가능하다.

영속성 관련 다양한 API 지원

  • 영속성 Persistence는 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성을 의미한다.
  • 결국, 영속성은 특정 데이터 구조를 이전 상태로 복원할 수 있게 하여 프로그램의 종료와 재개를 자유롭게 해준다.
  • IBatis / MyBatis / Hibernate 등, 이미 완성도 높은 DB 처리 라이브러리와 연결 가능한 Interface 제공한다.

높은 확장성 Scalability

  • Spring Framework에 통합하기 위해, 기존 라이브러리를 감싸는 정도로 사용이 가능하므로, 수많은 라이브러리가 지원된다.
  • Spring에서 사용되는 라이브러리를 별도로 분리하는 데에 용이하다.

0개의 댓글

관련 채용 정보