-
[ Spring ] 스프링 프레임워크란?JAVA 2022. 12. 9. 12:48728x90
Spring Framework
1. 프레임워크?
☞ 소프트웨서 개발에 있어 뼈대 역할을 하며, 특정 목적을 달성하기 위해 복잡한 문제들을 보다 쉽게 해결할 수 있도록 해주는 구조라고 할 수 있다. 앞서 말한 특정 목적을 달성하기 위해 그에 맞는 표준을 기반으로 여러 클래스와 라이브러리가 모인 형태이기 때문에 여러 개의 표준을 만들지 않아도 돼서 개발자의 할 일을 덜어준다. 예를 들어 한 프레임워크가 웹 프로그래밍용 프레임워크라면 웹 프로그래밍 구현을 위한 클래스와 라이브러리. 즉 페이지 구현, DB 관리, 세션 관리 등을 다루는 클래스와 라이브러리를 모아놓은 구조일 것이다. 그렇기 때문에 개발자가 0부터 프로그래밍을 시작하지 않아도 되는 수고를 덜어준다.
대표적인 웹 프로그래밍 프레임워크 예로, Java의 Spring, Python의 Django, Ruby의 Ruby on Rails가 있다.
2. 스프링 프레임워크란?
스프링 프레임워크는 의존성 주입(Dependency Injection) 프레임워크이다.

의존/종속(dependency)이라는 개념이 낯설 수 있지만, 두 개 이상의 클래스를 사용하여 프로그래밍을 해봤다면 그리 낯선 개념은 아니다. 웹 프로그램을 간단히 그려보면 그림과 같다.
크게 웹 층(web layer), 비즈니스 층(business layer), 데이터 층(data layer). 총 3개의 층으로 나눠볼 수 있다. 비즈니스 로직은 비즈니스 층에 있으며 데이터 층은 DB를 다루고 외부 인터페이스와 상호 작용하는 층이다.
만약 비즈니스 층에서 데이터 층의 클래스를 불러 무언가를 처리해야 하는 일이 있다면 그건 비즈니스 층이 데이터 층에 의존한다/종속된다고 할 수 있다. 만약 UI를 통해 어떤 것을 보여주고 싶다거나 사용자가 입력한 것을 DB에 저장하고 싶다면 일단 웹 층에서 비즈니스 층의 클래스를 호출해야 한다. 이 또한 웹 층이 비즈니스 층에 의존한다/종속된다는 것을 보여준다. 즉, 웹 층은 비즈니스 층에 의존하고/종속되고 비즈니스 층은 데이터 층에 의존/종속된다. 이러한 방식으로 웹 어플리케이션 구현하는 것이다. 그러니까 한 마디로, 무언가를 수행할 때 다른 어떤 것을 필요로 하고 그것을 호출하는 행위 자체가 그것에 의존적이라고 볼 수 있다는 것이다.
한 단계 더 깊게 들어가 엄청 복잡한 비즈니스 로직을 짠다고 가정해보자. 10, 3, 4. 이 3개의 숫자 집합이 있고 정렬(sort)을 하려고 한다. 이 정렬을 위한 알고리즘은 비즈니스 로직 클래스에 종속된다. 의존/종속(dependency)이라는 개념은 상당히 간단하다. 복잡한 비즈니스 로직이 어떤 것을 수행(service)한다고 할 때 무엇을 수행하는가? 이 경우에는 정렬 알고리즘을 수행한다.
클래스가 의존적이라는 것은 클래스가 기능 수행 시 기본적으로 필요한 모든 것들에 의존적이라고 할 수 있다(Dependency of a class is basically what are all the things it needs to be able to perform its functionality). 그러니까 우리는 이 의존성/종속성(Dependency)에 그리 낯가릴 필요가 없다는 것이다.
그렇다면 정렬을 사용해보도록 하자.
public class BusinessService { SortAlgorithm sortAlgorithm = new BubbleSortAlgorithm(); } public class BubbleSortAlgorithm implements SortAlgorithm { ... }이 코드에서 SortAlgorithm은 BusinessService에 종속되는 것을 알 수 있으며, '''SortAlgorithm ~ = new BubbleSortAlgorithm();''' 부분이 의존성이 생겨나는 구간인 것을 알 수 있다. 하지만 이 코드는 BusinessService가 직접적으로 인스턴스를 생성하며 강한 결합(Tight coupling)을 보여주는 코드이기 때문에 느슨한 결합(Loose coupling)으로 바꿔보자면 다음과 같다.
public class BusinessService { SortAlgorithm sortAlgorithm; public BusinessService(SortAlgorithm sortAlgorithm) { this.sortAlgorithm = sortAlgorithm; } } public class BubbleSortAlgorithm implements SortAlgorithm { ... }생성자를 통해 간접적으로 인스턴스를 생성하게 되면서 강한 결합이 느슨한 결합이 되었다. 느슨한 결합이 되면서 sortAlgorithm은 버블 정렬의 인스턴스가 될 수도 있고 퀵 정렬의 인스턴스가 될 수 있게 되었다. 생성자의 매개변수로 생성하고 싶은 구현체를 넣어주기만 하면 되니 말이다.
우리는 이 코드가 어떤 복합체(클래스)의 새로운 인스턴스를 생성하고 있다는 것을 알 수 있다. 이게 바로 스프링 프레임워크가 하는 일이다.
스프링은 객체의 인스턴스 생성함으로써 어디에서 의존성을 만들어낼지 결정하고 그 의존성을 관리한다. 이는 프로그래머는 그저 스프링 프레임워크에게 그렇게 하라고 말해주기만 하면 된다. 그럼 이쯤에서 의문이 들 것이다. 스프링이 BubbleSortAlgorithm 인스턴스를 생성하는 것을 어떻게 아는지, BusinessService의 인스턴스와 그 안에 BubbleSortAlgorithm이 생성되어야 하는지 어떻게 안다는 것인가? 그러니까 스프링이 이걸 어떻게 한다는 건데? 프로그래머가 스프링을 살짝 도와주기만 하면 된다. 스프링이 관리할 객체는 어떤 것인지 신원 정보를 알려주고(identify) 그 객체가 의존하는 것들은 무엇이 있는지 알려주면 된다.
스프링 프레임워크에서 중요한 어노테이션(annotation)이 2개 있다. 첫 번째는 @component이다.
@component public class BusinessService { SortAlgorithm sortAlgorithm; public BusinessService(SortAlgorithm sortAlgorithm) { this.sortAlgorithm = sortAlgorithm; } } @component public class BubbleSortAlgorithm implements SortAlgorithm { ... }BusinessService와 BubbleSortAlgorithm의 상단에 @component 어노테이션을 적어 스프링에게 이 두 클래스의 인스턴스를 관리하면 된다고 알려준다. 그럼 의존 여부(dependency)는 어떻게 알려주면 되는 것인가? 중요한 어노테이션 두 번째, @Autowired를 사용하면 된다.
@component public class BusinessService { @Autowired SortAlgorithm sortAlgorithm; public BusinessService(SortAlgorithm sortAlgorithm) { this.sortAlgorithm = sortAlgorithm; } } @component public class BubbleSortAlgorithm implements SortAlgorithm { ... }@Autowired를 작성하여 스프링으로 하여금 해당 객체의 의존성을 찾길 기대한다. 스프링은 @Autowired 어노테이션을 달고 있는 객체를 마주하면 내부적으로 @component 어노테이션 표시된 클래스(= 자신이 관리하는) 중 sortAlgorithm과 일치하는 클래스를 찾기 시작한다. BubbleSortAlgorithm의 인스턴스를 생성해서 BusinessService의 생성자에게 전달하고 해당 BusinessService의 인스턴스를 생성할 것이다.
따라서 스프링 프레임워크가 하는 일은 무엇인가? 스프링 프레임워크의 핵심은 무엇인가?
바로 의존성 주입(Dependency Injection)이다.
3. 주요 용어(terminology)
◆ Beans
☞ 스프링이 관리하는 인스턴스를 일컬어 bean이라고 한다. 각 bean들은 서로 다른 객체들이다.
◆ Autowiring
☞ 스프링이 의존 여부에 대해 확인하는 절차. 기본적으로 스프링은 어노테이션에 맞게 객체를 찾고
스턴스를 생성하고 그 객체가 의존하는 곳에 해당 인스턴스를 전달하는 절차라고 생각하면 된다.
◆ Dependency Injection (의존성 주입)
☞ 생성된 인스턴스가 의존하는 클래스에 해당 인스턴스를 종속 객체로 주입하는 것을 말한다.
◆ Inversion Of Control (제어의 역전)
☞ 생성자 등을 통해 인스턴스를 생성했지만 앞서 말했듯 스프링은 어노테이션을 통해 인스턴스를 생성하게 된다.
이런 통제에 대한 권한은 프로그래머에서 스프링으로 넘어갔다. 이를 일컫는 말이다.
◆ IOC Container
☞ 제어의 역전(inversion of control)을 실현하는 어떤 것을 일컫는 총칭이다.
스프링 프레임워크의 경우 전형적인 ioc container는 application context이다.
◆ Application Context
☞ application context는 생성되어 관리받는 모든 bean이 모여있는 곳이라 할 수 있다.
application context는 핵심 로직이 수행되는 곳이기 때문에 스프링 프레임워크에서 가장 중요한 부분이다.여기까지가 스프링 프레임워크를 처음 접한 사람이라면 이해해야 할 필수 개념이다.
728x90'JAVA' 카테고리의 다른 글
[ LinkedList] LinkedList 1 (0) 2022.12.09 [ LinkedList ] LinkedList란? (0) 2022.12.09 [ ArrayList ] indexOf(), lastIndexOf(), contains(), set(), toArray(), subList(), containsAll() 구현 03 (0) 2022.12.07 [ ArrayList ] get(), remove(), clear(), removeAll(), retainAll() 구현 02 (0) 2022.12.07 [ ArrayList ] size(), isEmpty(), add(), addAll() 구현 01 (0) 2022.12.05