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 |