Spring
Spring Framework는 Java 생태계에서 가장 대중적인 응용 프로그램 개발 Framework 이며, IoC(Inversion of Control: 제어의 역전), DI(Dependency Injection: 의존성 주입), AOP(Aspect Oriented Programming: 관점 지향 프로그래밍)라는 특징을 가지고 있습니다.
IoC(Inversion of Control: 제어의 역전)
메서드나 객체의 호출 작업을 개발자가 결정하는 것이 아닌 프레임워크 내부의 Container가 제어하기 때문에 이를 IoC(제어의 역전)라고 부릅니다.
보다 자세한 내용은 아래의 포스팅에서 확인해주세요.
DI(Dependency Injection: 의존성 주입)
먼저 의존 관계(Dependency)는 아래와 같이 B Class가 A Class를 내부 변수로 사용함으로써 생기게 됩니다.
class AClass{
var id: Int = 1
}
class BClass{
var aclassInstance = AClass()
}
그리고 주입(Injection)이란 외부에서 객체를 생성하여 해당 객체를 클래스 내부로 주입하는 것을 의미합니다.
class AClass{
var id: Int = 1
}
class BClass(var aclassInstance: AClass){
}
fun main(){
val a = AClass()
// Injection
val b = BClass(a)
print(b.aclassInstance)
}
그러나 단순히 의존성이 있는 Class의 객체를 주입한다고 해서 이를 DI(Dependency Injection)이라고 부르지는 않습니다.
두 개의 Class가 강하게 의존하고 있을 때 의존성을 주입함으로써 의존성을 낮출 수 있는 경우에만 DI(Dependency Injection)라고 부른다고 알고 있습니다. (100% 확실한 내용은 아님)
예를 들어 아래와 같이 연필(PenCli Class)이라는 상품을 판매하는 상점(Store Class)이 있다고 가정해보겠습니다.
class Pencli{
var price = 1000
}
class Store{
var pencli: Pencli
init{
this.pencli = Pencli()
}
}
위 예시에서 두 클래스는 강하게 의존하고 있습니다. 도대체 강하게 의존한다는 말이 무슨 의미일까요?
만약, Store Class에서 Pencli Class가 아닌 Food Class와 관계를 맺고 싶다면 Store Class의 코드 변경 없이는 관계를 맺을 수 없습니다. 이렇게 결합도가 강해 유연성이 떨어지는 상황을 바로 의존성이 강하다라고 표현할 수 있습니다.
이러한 상황을 의존성(Dependency)을 주입(Injection)함으로써 해결할 수 있다면 DI(Dependency Injection)을 했다고 볼 수 있습니다.
interface Product{
var price: Int
}
class Pencli: Product{
override var price = 1000
}
class Food: Product{
override var price = 3000
}
class Store(val product: Product){
fun getPrice():Int{
return this.product.price
}
}
fun main(){
val pencli = Pencli()
val food = Food()
var store = Store(pencli)
println(store.getPrice()) // output >> 1000
store = Store(food)
println(store.getPrice()) // output >> 3000
}
그리고 Spring에서는 IoC Container를 이용하여 애플리케이션의 실행 시점에 객체(Bean)를 생성하고 의존성을 주입함으로써 객체간의 관계를 형성할 수 있습니다.
이와 같은 내용은 "Spring에서 의존성 주입(DI)이란 애플리케이션의 실행 시점에 강하게 결합된 클래스들을 분리하고 객체 간의 관계를 결정하는 것으로 결합도를 낮추고 유연성을 확보할 수 있다."라는 문장으로 정리할 수 있습니다.
@Service
class Store{
val product: Product
@Autowired
constructor(product: Product){
this.product = product
}
}
※ @Autowired는 IoC Container에서 Bean이 생성된 이후 @Autowired가 설정된 메서드가 호출되어 객체가 자동으로 주입되는 기능을 갖고 있습니다.
AOP(Aspect Oriented Prgramming)
AOP는 관점 지향 프로그래밍이라고도 불리는데 관점 지향이란 어떤 로직을 기준으로 핵심적인 관점과 부가적인 관점으로 나눠 본다는 의미이며 관점 지향 프로그래밍은 관점을 기준으로 각각 모듈화하는 프로그래밍 기법을 의미합니다.
여러 클래스, 메서드에 걸쳐 나타나는 비슷한 코드들을 Concern이라고 부르는데, 아래의 그림에서 색깔 하나당 하나의 Concern을 나타낸다고 가정해보겠습니다.
AOP 주요 목적에 대하여 조금 더 쉽게 설명해보자면 "각 클래스에 존재하는 Concern을 Aspect으로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다." 라고 설명할 수 있습니다.
※ Aspect : 흩어진 관심사(Crosscutting Concerns)를 묶어서 모듈화 한 것으로 하나의 모듈을 나타냄
지금까진 설명드린 것처럼 Spring은 갖고 있는 특성으로 인해 다양한 모듈을 사용할 수 있지만 다양한 기능을 사용하기 위해 필요한 절차가 너무나도 복잡하여 많은 사용자들이 불편함을 느꼈습니다.
Spring Boot
이러한 불편함을 없애고자 나온 것이 바로 Spring Boot이며 공식 설명에서도 단지 실행만 하면 된다고 말하고 있습니다.
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
그렇다면 Spring Boot는 정확히 어떤 점이 다른 걸까요?
기존에 Spring을 사용할 경우 각 라이브러리별 버전을 명시하고 해당 버전에 종속된 모든 라이브러리를 직접 찾아서 다시 명시해줘야했습니다. 그러나 Spring Boot에서는 Spring Boot Starter를 통하여 버전 관리를 자동으로 해줌으로써 라이브러리의 종속성이나 호환 문제에 대하여 신경쓸 필요가 없어지게 되었습니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
또 다른 점으로 Spring Boot에서는 Tomcat이 내장되어 있기 때문에 별도의 Tomcat 설정을 할 필요가 없어졌으며 그렇기 때문에 독립적으로 실행 가능한 jar로 손쉽게 배포가 가능해지게 되었습니다.
이 외에도 여러 차이점(XML 설정을 사용하지 않아도 됨)이 있지만 중요한 포인트에 대해서는 설명을 전부 드린 것 같습니다.
만약 추가로 궁금하신 부분이 있으시다면 Spring Boot의 공식 사이트를 참고해주세요.
'Study > WEB' 카테고리의 다른 글
URI, URL, URN의 차이점 (0) | 2022.08.17 |
---|---|
Kotlin에 대하여 알아보자 (0) | 2022.08.01 |
[Spring Boot With Kotlin] Spring Interceptor (0) | 2022.07.25 |
[Spring Boot] Bean 이해하기 (With Spring Container) (0) | 2022.07.25 |
[Spring Boot With Kotlin] RESTFul API, JSON 데이터 처리하기 (0) | 2022.07.24 |
댓글