JAVA

SpringBoot VS Spring

euicheol0910 2025. 6. 16. 01:55

Spring Framework는 Java 기반의 엔터프라이즈 애플리케이션 개발을 위한 오픈소스 프레임워크입니다.
Java EE(현 Jakarta EE)의 복잡함을 줄이기 위해 등장했으며, 객체지향 원칙에 충실하게 설계된 구조 덕분에 많은 개발자들이 사용하고 있습니다.

Spring의 특징

  • IoC (제어의 역전)
    객체의 생성과 관리를 개발자가 아닌 프레임워크가 맡습니다.
// 일반적인 방식
UserService service = new UserService(); 

// IoC 방식 (Spring이 관리)
@Component
public class UserService {
    public void join() {
        System.out.println("회원 가입 로직");
    }
}

// 사용
@Autowired
UserService userService; // Spring이 자동 주입해줌

 

  • DI (의존성 주입)
    객체 간의 의존 관계를 외부에서 주입함으로써 결합도를 낮춥니다.

[직접 생성: 결합도가 높음]

public class OrderService {
    private PaymentService paymentService = new PaymentService(); // 직접 생성

    public void order() {
        paymentService.pay(); // 직접 만든 객체에 의존
    }
}
  • OrderService는 무조건 PaymentService를 써야 하고, 바꿀 수도 없음
  • 테스트할 때 MockPaymentService 같은 걸 넣기도 어려움
  • new를 직접 하므로 다른 구현체로 바꾸려면 코드 수정이 필요함

 

[외부 주입: 결합도가 낮음 → DI]

public class OrderService {
    private final PaymentService paymentService;

    // 생성자를 통해 외부에서 주입 (DI)
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    public void order() {
        paymentService.pay(); // 어떤 구현체인지 몰라도 동작함
    }
}

 

 

  • OrderService는 PaymentService에 의존은 하지만,
    구체적인 구현체는 몰라도 됨
  • 외부에서 어떤 구현체(KakaoPay, CardPay, MockPay)든 넣을 수 있음

 

  • AOP (관점 지향 프로그래밍)
    로깅, 보안, 트랜잭션 같은 부가기능을 핵심 로직과 분리하여 코드의 관심사를 분리합니다.
@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("메서드 실행 전: " + joinPoint.getSignature().getName());
    }
}
@Component
public class SampleService {
    public void doSomething() {
        System.out.println("업무 처리 로직");
    }
}
1. SampleService.doSomething() 호출
2. @Before Advice 실행 → "메서드 실행 전: doSomething"
3. 실제 로직 실행 → "업무 처리 로직"

 

  • 트랜잭션 관리
    선언적 트랜잭션 관리가 가능해 비즈니스 로직에만 집중할 수 있게 합니다.

 

@Transactional 사용한 코드 (Spring이 트랜잭션 자동 관리)

@Service
public class AccountService {

    @Transactional // 트랜잭션 시작, 정상 종료 시 커밋, 예외 시 롤백
    public void transferMoney(Long fromId, Long toId, int amount) {
        withdraw(fromId, amount); // 출금
        deposit(toId, amount);    // 입금
    }

    private void withdraw(Long id, int amount) {
        // 계좌에서 금액 차감
    }

    private void deposit(Long id, int amount) {
        // 계좌에 금액 추가
    }
}

 

@Transactional 없이 수동 트랜잭션 처리

@Service
public class AccountService {

    @PersistenceContext
    private EntityManager em;

    public void transferMoney(Long fromId, Long toId, int amount) {
        EntityTransaction tx = em.getTransaction();

        try {
            tx.begin(); // 트랜잭션 수동 시작

            withdraw(fromId, amount); // 출금
            deposit(toId, amount);    // 입금

            tx.commit(); // 커밋
        } catch (Exception e) {
            tx.rollback(); // 예외 발생 시 롤백
            throw e;
        }
    }

    private void withdraw(Long id, int amount) {
        // DB에서 계좌 조회 후 차감
    }

    private void deposit(Long id, int amount) {
        // DB에서 계좌 조회 후 추가
    }
}

 

단점은?

1. XML 설정이 복잡함 (applicationContext.xml)

<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 컴포넌트 스캔 -->
    <context:component-scan base-package="com.example.service" />

    <!-- 빈 수동 등록 -->
    <bean id="userService" class="com.example.service.UserService" />
    <bean id="paymentService" class="com.example.service.PaymentService" />

    <!-- 트랜잭션 설정 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
//복잡하고 길며, 실수도 잦음. 변경할 때마다 XML을 열어 수정해야 했음.

2. Java 기반 설정도 복잡함 (@Configuration 기반 수동 등록)

@Configuration
public class AppConfig {

    @Bean
    public PaymentService paymentService() {
        return new PaymentService();
    }

    @Bean
    public UserService userService() {
        return new UserService(paymentService());
    }
}
// XML보다는 낫지만 여전히 Bean 생성/주입을 수동으로 관리해야 함

 

Spring Boot란?

 

개념

Spring Boot는 Spring Framework를 기반으로, 복잡한 설정 없이 빠르게 프로젝트를 시작할 수 있게 해주는 도구입니다.
기본 설정과 구조를 자동으로 구성해주고, 개발자가 비즈니스 로직 구현에 집중할 수 있도록 도와줍니다.

주요 특징

자동 설정 (Auto Configuration)
애플리케이션에 존재하는 클래스들을 기반으로 자동으로 설정을 적용합니다.

// DemoApplication.java
@SpringBootApplication // → @EnableAutoConfiguration 포함
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

// 자동으로 Controller, DispatcherServlet, Jackson 등이 설정됨
@RestController
public class HelloController {
    @GetMapping("/")
    public String hello() {
        return "Hello, Spring Boot!";
    }
}

 

 

내장 서버 제공
톰캣(Tomcat), 제티(Jetty), 언더토우(Undertow) 등 내장 WAS 지원 → java -jar 명령어만으로 실행 가능

 

스프링 애플리케이션의 기본 구조 제공
프로젝트 생성 시 기본 디렉토리 구조와 설정 파일이 자동 생성됨

src/
 └── main/
     ├── java/com/example/demo
     │   └── DemoApplication.java
     └── resources/
         ├── application.yml
         ├── static/
         └── templates/

 

Spring Initializr
웹 기반 UI를 통해 몇 번의 클릭만으로 프로젝트 템플릿을 생성할 수 있음

 

모듈화 구조
필요한 모듈만 선택해서 사용할 수 있음
(예: Spring Core, Spring MVC, Spring Security, Spring Data 등)

<!-- pom.xml -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.20.RELEASE</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.5</version>
</dependency>

<!-- 필요한 모든 라이브러리를 일일이 명시해야 했음 -->
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'       // 웹 MVC + 내장 Tomcat
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'  // JPA + Hibernate
    implementation 'org.springframework.boot:spring-boot-starter-security'  // 로그인, 권한, 인증
    implementation 'com.h2database:h2'                                       // H2 DB (개발용 DB)
}

Spring vs Spring Boot 차이점 비교

항목  Spring Framework  Spring Boot
설정 방식 수동 설정 (XML, Java Config) 자동 설정 (Auto Configuration)
실행 환경 외부 웹서버(Tomcat 등) 필요 내장 웹서버 포함 (별도 설정 없이 실행 가능)
프로젝트 구조 개발자가 직접 구성 초기 구조 자동 생성
라이브러리 의존성 관리 직접 하나하나 추가해야 함 Starter로 한 번에 쉽게 설정 가능
생산성 상대적으로 낮음 높은 생산성과 빠른 개발 가능
목표 유연성과 확장성 중심 빠른 개발, 운영 효율성 중심

 

 

결론 및 요약

  • Spring은 강력하고 유연한 프레임워크지만, 설정이 복잡하고 진입 장벽이 높을 수 있습니다.
  • Spring Boot는 Spring의 복잡한 설정을 줄이고, 개발자가 바로 비즈니스 로직을 구현할 수 있도록 도와주는 도구입니다.
  • 둘은 경쟁 관계가 아니라 보완 관계이며, Spring Boot는 Spring의 사용성을 높이기 위한 확장 프레임워크입니다.

'JAVA' 카테고리의 다른 글

프록시 패턴과 AOP  (0) 2025.05.26
POJO  (4) 2025.05.21
JAVA 깊은 복제와 얕은 복제  (1) 2025.04.28
JAVA 어노테이션  (0) 2025.04.28
자바의 제네릭에 대하여  (3) 2025.04.23