티끌모아 로키산맥 🏔
search
로ᄏl
배움에 끝은 없다... 개발 또한 그러하다.
Today
Yesterday
해당 내용은 '코드로 배우는 스프링 웹 프로젝트' 책을 공부하면서 정리한 내용입니다.
프레임 워크는 '뼈대나 근간을 이루는 코드들의 묶음' 이라고 할 수 있다. 스프링은 인기 있는 프레임워크이다. 많은 프레임워크 중에서도 스프링 프레임워크가 인기있는 이유는 아래와 같은 스프링의 차별성 때문이다.
스프링의 주요한 변화는 다음과 같다.
스프링의 성격 자체가 가벼운 프레임워크지만, 그 내부에는 객체 간의 관계를 구성할 수 있는 특징을 가지고 있다. 스프링은 다른 프레임워크들과 달리 이 관계를 구성할 때 별도의 API 등을 사용하지 않는 POJO(Plain Old Java Object)의 구성만으로 가능하도록 제작되어 있다. 쉽게 말해 일반적인 Java 코드를 이용해서 객체를 구성하는 방식을 그대로 스프링에서 사용할 수 있다는 얘기다.
이것이 중요한 이유는 코드를 개발할 때 개발자가 특정한 라이브러리나 컨테이너의 기술에 종속적이지 않다는 것을 의미하기 때문이다. 개발자는 가장 일반적인 형태로 코드를 작성하고 실행할 수 있기 때문에 생산성에도 유리하고, 코드에 대한 테스트 작업 역시 좀 더 유연하게 할 수 있다는 장점이 생긴다.
스프링에 대한 얘기를 하면서 빠지지 않는 개념이 이 '의존성 주입'이라는 개념이다. 의존성(Dependency)이라는 것은 하나의 객체가 다른 객체 없이 제대로 된 역할을 할 수 없다는 것을 의미한다. (흔히 A 객체가 B 객체 없이 동작이 불가능한 상황을 'A가 B에 의존적이다'라고 표현한다)
'주입(Injection)'은 말 그대로 외부에서 '밀어 넣는 것'을 의미한다. 의존성과 주입을 결합해서 생각해 보면 '어떤 객체가 필요한 객체를 외부에서 밀어 넣는다'는 의미가 된다. 그렇다면 왜 외부에서 객체를 주입하는 방식을 사용하는지에 대한 의문이 들것이다. 그 이유는 '주입을 받는 입장에서는 어떤 객체인지 신경 쓸 필요가 없다'는 것이다. 즉 '어떤 객체에 의존하든 자신이 역할은 변하지 않는다'와 같은 의미이다.
'의존성 주입' 방식을 사용하려면 추가적인 하나의 존재가 필요하게 된다. 이 존재는 의존성이 필요한 객체를 찾아서 '주입'하는 역할을 하게된다.
스프링은 이러한 구조를 만드는데 적합한 구조로 설계되어 있다. 스프링에서는 'ApplicationContext'라는 존재가 필요한 객체들을 생성하고, 필요한 객체들을 주입하는 역할을 해주는구조이다. 따라서 스프링을 이용하면 개발자들은 기존의 프로그래밍과달리 객체와 객체를 분리해서 생성하고, 이러한 객체들을 엮는(wiring) 작업을 하는 형태의 개발을 하게 된다. 스프링에서는 ApplicationContext가 관리하는 객체들을 '빈(Bean)'이라는 용어로 부르고, 빈과 빈 사이의 의존관계를 처리하는 방식으로 XML 설정, 어노테이션 설정, Java 설정 방식을 이용할 수 있다.
좋은 개발환경의 중요 원칙은 '개발자가 비즈니스 로직에만 집중할 수 있게 한다.' 이다. 이 목표를 이루기 위해서는 몇 가지 중요한 원칙이 있지만, 가장 쉽게 생각할 수 있는 것이 '반복적인 코드의 제거'라고 할 수 있다. 스프링은 프레임워크를 이용한 개발은 이러한 반복적인 코드를 줄이고, 핵심 비즈니스 로직에만 집중할 수 있다.
대부분의 시스템이 공통으로 가지고 있는 보안, 로그, 트랜잭션 같이 비즈니스 로직은 아니지만, 반드시 처리가 필요한 부분을 스프링에서는 '횡단 관심사(cross-concern)'라고 한다. 스프링은 이러한 횡단 관심사를 분리해서 제작하는 것이 가능하다. AOP(Aspect Orinted Programming)는 이러한 횡단 관심사를 모듈로 분리하는 프로그래밍의 패러다임이다.
스프링은 AOP를 AspectJ의 문법을 통해서 작성할 수 있는데, 이를 통해서 개발자는 1) 핵심 비즈니스 로직에만 집중해서 코드를 개발할 수 있게 되었고, 2) 각 프로젝트마다 다른 관심사를 적용할 때 코드의 수정을 최소화시킬 수 있었으며, 3) 원하는 관심사의 유지보수가 수월한 코드를 구성할 수 있다.
데이터베이스를 이용할 때 반드시 신경 써야 하는 부분은 하나의 업무가 여러 작업으로 이루어지는 경우의 트랜잭션 처리이다. 이 트랜잭션 처리는 상황에 따라서 복잡하게 구성될 수도 있고, 아닐 수도 있는데, 그때마다 코드를 이용해서 처리하는 작업은 개발자에게는 상당히 피곤한 일이다. 스프링은 이런 트랜잭션의 관리를 어노테이션이나 XML로 설정할 수 있기 때문에 개발자가 매번 상황에 맞는 코드를 작성할 필요가 없도록 설계되었다.
스프링이 동작하면 생기는 일
(Restaurant 객체의 필드에 Chef가 있고 이는 @Autowird 속성이 있다)
[Spring] NoUniqueBeanDefinitionException 예외 해결방법 (0) | 2023.08.15 |
---|---|
코틀린 스프링에서의 이벤트 처리 (with 유스콘) (0) | 2022.01.12 |
[Spring] 싱글톤 레지스트지와 Bean Scope (0) | 2021.12.12 |
Spring - 의존성 주입(DI)을 '생성자 주입 방식'으로 권장하는 이유 (0) | 2020.12.20 |
@Get, @Post, Delete, @Put, @Patch Mapping (0) | 2020.01.09 |