둘 다 Spring Framework입니다.
Spring Boot가 Spring에 비해 여러가지 장점이 있습니다.
Dependency등록이 쉽다. maven이나 gradle를 사용하면 코드 몇줄로 dependecy를 추가할수 있다.
코드 자체가 확실히 짧아지고 버전도 권장 버전으로 설정 가능하다. configuration에서도 마찬가지이다.
내장서버를 제공한다. 외장서버를 불러들이지 않으니 구동시간도 훨씬 짧아진다. 또한 배포를 위해 War파일을 통해 Tomcat에 배포할 필요도 없다. ex) java -jar $REPOSITORY/&JAR_NAME
Security, JPA에 대한 사용도 훨씬 쉽다.
개발에만 쉽게 집중할수 있게 해주는데 어지간하면 Spring Boot쓰자요.
개발자가 객체를 생성하고 관리하는 것이 아니라 프레임워크에게 생성 역할을 부여한다.
public class User () {
String nickName;
String password;
}
public static void main(String[] args) {
User user = new User();
}
객체 생성의 예시입니다. 클라이언트가 new로 직접 객체를 생성합니다. 생성 뿐만 아니라 초기화, 소멸, 메소드 호출등의 작업을 객체의 생명주기를 관리한다고 합니다. 하지만 프레임워크는 어떨까요? Service, Repository를 사용할 때 new 연산자를 이용하여 객체를 생성하진 않았습니다. @Autowired, @ComponentScan등을 통해 호출만 했습니다. 생명주기를 프레임워크에게 위임한겁니다. 개발자가 아닌 프레임워크가 생명주기를 관리하는 것, 이를 제어의 역전이라 합니다. 참고로 이러한 객체(오브젝트)를 스프링에서는 Bean이라 합니다.
제어의 역전이 무엇인지는 알겠는데 어떤 장점이 있길래 쓰는 걸까요?
→ 높응낮결을 하게해준다.
이를 통해 라이브러리와 프레임워크의 가장 큰 차이점을 알수 있습니다. 라이브러리는 개발자가 직접 호출하여 객체의 생명주기를 관리하지만 프레임워크는 반대입니다.
IoC와 DI는 동일한 개념이 아닙니다. DI는 IoC를 구현하기 위해 사용하는 디자인 패턴입니다.
예시를 통해 알아보겠습니다.
public class OrderService {
private DBConnection dbConnection;
public OrderService() {
dbConnection = new DBConnection(); // 직접 생성
}
public void processOrder(Order order) {
// 주문 처리 로직
dbConnection.save(order); // DBConnection에 의존하여 저장
}
}
OrderService는 DBConnection클래스에 의존하고 있습니다. 의존성이 높아서 DBConnection의 변경이 발생하면 수정이 번거롭습니다.
public class OrderService {
private DBConnection dbConnection;
public OrderService(DBConnection dbConnection) {
this.dbConnection = dbConnection; // 주입 받음
}
public void processOrder(Order order) {
// 주문 처리 로직
dbConnection.save(order); // 주입받은 DBConnection 사용
}
}
마찬가지로 OrderService는 DBConnection를 의존하고 있지만 어떤 종류의 DBConnection를 주입받던지간에 OrderService는 상관없습니다.
DI는 쉽게 말해 객체 간의 의존관계를 외부(스프링 컨테이너)에서 결정하고 주입하는 것입니다.
의존성 주입방법엔 총 3가지가 있습니다. 생성자 주입, Setter 주입, 인터페이스 주입.
인터페이스 주입은 걍 패스할게요. Setter주입은 지금은 권장하지 않고 생성자 주입을 사용하라고 합니다.
왜일까요? 객체가 생성되는 시점에 Bean을 주입하기 때문에 NPE를 방지할 수 있습니다. 또한 final로 선언하므로 불변성을 활용할 수도 있습니다. Setter 주입시 발생할 수 있는 순환 참조 오류도 사전에 방지할 수 있습니다.
그림을 통해 쉽게 이해해봐요.
막말로 개발자는 Business Logic박스를 제외하고 어떻게 작동하는지 몰라도 애플리케이션을 구현할 수 있습니다. Request가 오면 알아서 호출해주니까요. 이 전에는 불편해서 어땠는지 몰라 참.
이전까지는 IoC가 DI와 동일한줄 알았고 어떤 개념인지도 정확하게 몰랐다. 이 글을 작성하면서 개념과 차이점에 대해서도 알게되었고 객체 간의 관계를 느슨하게 하여 코드를 보다 유연하게 짤 수 있게 되었다. 요건사항에 맞게 프로덕트를 만드는 것도 중요하지만 low level를 이해하는것도 중요하다고 생각한다. 카레이서가 자동차의 내부 부품의 역할을 알필요는 없겠지만 동작원리를 알아야 적절한 코너링과 감속/가속 타이밍을 알지 않을까? 이후엔 AOP와 트랜잭션에 대해 알아보겠습니다.
개발자로서 성장하는 데 큰 도움이 된 글이었습니다. 감사합니다.