소프트웨어 기술(스타트업 위주)

spring-boot

spring-boot 정리 입니다. 추가적인 자세한 설명 및 툴 이용 방법은 각 목차별로 공식문서 페이지로 하이퍼링크 참조하겠습니다.


1. Spring Core

1.1 Configuration

Spring에서 설정(Configuration)은 애플리케이션의 동작을 정의하고 구성하는 역할을 합니다. @Configuration 어노테이션을 사용하면 Java 기반 설정 클래스를 정의할 수 있으며, @Bean을 사용하여 특정 객체를 Spring 컨테이너에 등록할 수 있습니다. 이를 통해 XML 기반의 설정을 사용하지 않고도 애플리케이션을 유연하게 구성할 수 있습니다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }
}

1.2 Dependency Injection

의존성 주입(Dependency Injection, DI)은 객체 간의 의존성을 Spring 컨테이너가 관리하도록 위임하는 개념입니다. 이를 통해 객체 간의 결합도를 낮추고, 코드의 유지보수성과 테스트 용이성을 증가시킬 수 있습니다. Spring에서는 @Autowired 어노테이션을 사용하여 자동으로 의존성을 주입할 수 있습니다.

import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

@Service
public class MyService {
    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
}

1.3 Spring IOC

IOC(Inversion of Control, 제어의 역전)는 객체의 생성, 초기화, 소멸을 개발자가 직접 관리하는 것이 아니라 Spring 컨테이너가 관리하는 개념입니다. 이를 통해 객체 간의 결합도를 줄이고 유연한 구조를 가질 수 있습니다. Spring의 ApplicationContext는 빈(bean)의 라이프사이클을 관리하는 핵심 컨테이너입니다.

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        MyService myService = context.getBean(MyService.class);
        System.out.println(myService);
    }
}

1.4 Spring AOP

AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)은 핵심 비즈니스 로직과 공통적으로 적용되는 기능(로깅, 트랜잭션 관리, 보안 등)을 분리하여 모듈화하는 프로그래밍 기법입니다. Spring에서는 @Aspect@Before, @After, @Around 등의 어노테이션을 활용하여 특정 메서드 실행 전후에 공통 기능을 적용할 수 있습니다.

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void logBeforeMethod() {
        System.out.println("메서드 실행 전 로그");
    }
}

1.5 Spring MVC

Spring MVC는 Model-View-Controller 패턴을 기반으로 한 웹 프레임워크입니다. 컨트롤러(@Controller 또는 @RestController)를 사용하여 클라이언트 요청을 처리하고, 뷰(View)와 모델(Model) 데이터를 연결할 수 있습니다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class MyController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello, Spring MVC!";
    }
}

1.6 Annotations

Spring에서는 다양한 어노테이션을 제공하여 개발을 편리하게 합니다.

  • @Component: 일반적인 빈으로 등록할 때 사용
  • @Service: 서비스 계층을 나타낼 때 사용
  • @Repository: 데이터 액세스 계층을 나타낼 때 사용
  • @Controller: 웹 컨트롤러 역할 수행
  • @Autowired: 의존성 자동 주입
  • @Qualifier: 특정 빈을 선택할 때 사용
  • @Configuration: Java 기반 설정 클래스
  • @Bean: 수동 빈 등록
import org.springframework.stereotype.Service;

@Service
public class UserService {
    // 비즈니스 로직
}

1.7 Spring Bean Scope

Spring에서는 빈의 생명 주기를 제어하기 위해 다양한 스코프를 제공합니다.

  • singleton (기본값): 하나의 빈 인스턴스를 애플리케이션 내에서 공유
  • prototype: 매번 새로운 인스턴스를 생성
  • request: HTTP 요청마다 새로운 인스턴스를 생성 (웹 애플리케이션에서 사용)
  • session: 사용자 세션마다 하나의 인스턴스를 유지
  • application: 애플리케이션 전체에서 하나의 인스턴스를 유지
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class PrototypeBean {
    public PrototypeBean() {
        System.out.println("Prototype Bean 생성됨");
    }
}

2. Spring Security

2.1 Authentication

인증(Authentication)은 사용자의 신원을 확인하는 과정입니다. Spring Security에서는 사용자 정보를 UserDetailsService를 통해 관리할 수 있으며, 메모리 기반 또는 데이터베이스 기반 인증을 설정할 수 있습니다.

import org.springframework.context.annotation.Bean;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Bean
public UserDetailsService userDetailsService() {
    UserDetails user = User.withDefaultPasswordEncoder()
        .username("user")
        .password("password")
        .roles("USER")
        .build();
    return new InMemoryUserDetailsManager(user);
}

2.2 Authorization

인가(Authorization)는 사용자가 특정 리소스에 접근할 수 있는 권한을 부여하는 과정입니다. Spring Security에서는 역할(Role) 기반 접근 제어를 제공합니다.

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
            .requestMatchers("/admin").hasRole("ADMIN")
            .anyRequest().authenticated()
        ).formLogin();
        return http.build();
    }
}

2.3 OAuth2

OAuth2를 사용하면 Google, Facebook, GitHub 등의 외부 인증 제공자를 통해 로그인할 수 있습니다.

import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.oauth2Login();
        return http.build();
    }
}

2.4 JWT Authentication

JWT(JSON Web Token)는 인증 및 권한 부여를 위해 사용되는 토큰 기반 인증 방식입니다.

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtUtil {
    private static final String SECRET_KEY = "mySecretKey";

    public static String generateToken(String username) {
        return Jwts.builder()
            .setSubject(username)
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
            .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
            .compact();
    }
}

3. Spring Boot Starters

Spring Boot Starters는 Spring 애플리케이션 개발을 쉽게 하기 위해 제공되는 의존성 관리 패키지이다. 이들은 특정 기능을 구현하는 데 필요한 모든 종속성을 미리 정의하고 구성하여 개발자가 직접 설정할 필요 없이 간단히 추가할 수 있도록 돕는다.

Spring Boot의 공식 Starters는 spring-boot-starter-* 형식을 따르며, 일반적으로 필요한 모든 관련 라이브러리를 포함한다.

3.1 주요 Spring Boot Starters

Starter NameDescription
spring-boot-starter-webSpring MVC 기반 웹 애플리케이션을 개발할 때 사용
spring-boot-starter-data-jpaJPA 및 Hibernate를 활용한 데이터 액세스를 제공
spring-boot-starter-securitySpring Security를 활용한 인증 및 권한 부여 기능 제공
spring-boot-starter-thymeleafThymeleaf 템플릿 엔진을 활용한 View 개발
spring-boot-starter-testJUnit, Mockito, Spring Test 등을 포함하는 테스트 환경 제공

3.2 예제: spring-boot-starter-web 사용하기

spring-boot-starter-web을 이용하여 간단한 RESTful API를 구축할 수 있다.

pom.xml에 의존성 추가 (Maven 사용 시)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

간단한 REST 컨트롤러 구현

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class HelloController {

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, Spring Boot Starter!";
    }
}

애플리케이션 실행 (Application 클래스 작성)

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

4. AuthConfiguration

Spring Security를 활용한 인증 및 권한 부여를 설정하는 방법을 설명한다.

4.1 Spring Security 설정하기

Spring Boot에서는 spring-boot-starter-security를 이용하여 인증 및 권한 부여를 간편하게 설정할 수 있다.

pom.xml에 의존성 추가

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
</dependencies>

Security Configuration 클래스 작성

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .requestMatchers("/user/**").hasRole("USER")
                .anyRequest().authenticated()
            )
            .formLogin()
            .and()
            .logout();
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();

        UserDetails admin = User.withDefaultPasswordEncoder()
                .username("admin")
                .password("admin123")
                .roles("ADMIN")
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }
}

실행 후 로그인 테스트

  • 애플리케이션 실행 후 브라우저에서 http://localhost:8080에 접근하면 로그인 페이지가 표시된다.
  • user/password 또는 admin/admin123을 입력하여 로그인하면 역할에 따라 페이지 접근이 달라진다.

5. Hibernate

5.1 Transactions

Hibernate에서 트랜잭션은 데이터의 일관성을 유지하면서 여러 작업을 하나의 논리적 단위로 묶어 원자적으로 실행할 수 있도록 하는 중요한 개념이다. 트랜잭션을 사용하면 모든 작업이 성공적으로 완료되거나, 하나라도 실패하면 전체 작업을 롤백할 수 있다. 이는 ACID(Atomicity, Consistency, Isolation, Durability) 속성을 보장하는 핵심 메커니즘이다.

  • 예제 코드 (Spring + Hibernate)
import org.hibernate.Session;
import org.hibernate.Transaction;

public class HibernateTransactionExample {
    public static void main(String[] args) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction transaction = null;

        try {
            transaction = session.beginTransaction();
            User user = new User("John Doe", "john@example.com");
            session.save(user);
            transaction.commit(); // 모든 작업이 성공적으로 완료되면 커밋
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback(); // 오류 발생 시 롤백
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

5.2 Relationships

Hibernate에서 엔티티 간의 관계(Association)는 데이터베이스 테이블 간의 관계를 매핑하는 방식이다. 올바른 관계 설정을 통해 데이터 무결성을 유지하고, 효율적인 데이터 조회를 수행할 수 있다.

Hibernate의 주요 관계 유형:

  • One-to-One (@OneToOne): 한 엔티티가 다른 하나의 엔티티와만 연결됨.

  • One-to-Many (@OneToMany): 한 엔티티가 여러 개의 관련 엔티티를 가질 수 있음.

  • Many-to-One (@ManyToOne): 여러 엔티티가 하나의 엔티티를 참조할 수 있음.

  • Many-to-Many (@ManyToMany): 여러 개의 엔티티가 여러 개의 다른 엔티티와 연관될 수 있음.

  • 예제 코드 (One-to-Many 관계)

@Entity
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
    private List<Employee> employees = new ArrayList<>();
}

@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "department_id")
    private Department department;
}

5.3 Entity Lifecycle

Hibernate에서 엔티티 라이프사이클은 객체가 데이터베이스 및 영속성 컨텍스트와 어떻게 상호작용하는지를 정의한다. 엔티티 상태는 다음과 같다.

  • Transient (비영속): 엔티티가 생성되었지만 아직 데이터베이스에 저장되지 않은 상태.

  • Persistent (영속): 엔티티가 영속성 컨텍스트에 포함되어 관리되는 상태. save(), persist() 등에 의해 영속 상태로 변경됨.

  • Detached (준영속): 영속성 컨텍스트에서 분리된 상태. evict(), clear(), close() 등의 메서드 호출로 변경됨.

  • Removed (삭제됨): 데이터베이스에서 삭제될 예정인 상태. delete() 메서드가 호출되면 이 상태로 변경됨.

  • 예제 코드 (엔티티 상태 변경)

Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = session.beginTransaction();

User user = new User("Alice", "alice@example.com"); // Transient 상태
session.save(user); // Persistent 상태
session.evict(user); // Detached 상태
session.delete(user); // Removed 상태

transaction.commit();
session.close();

6. Spring Data

6.1 Spring Data JPA

Spring Data JPA는 Hibernate와 같은 ORM 프레임워크를 기반으로 한 데이터 접근 기술로, 복잡한 데이터 처리 로직을 단순화하고 자동으로 CRUD 메서드를 제공한다. 이를 통해 개발자는 SQL 작성 없이 데이터베이스와 상호작용할 수 있다.

  • 예제 코드 (Spring Data JPA Repository)
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByEmail(String email);
}

6.2 Spring Data JDBC

Spring Data JDBC는 JPA보다 가볍고 간결한 데이터 접근 방식을 제공하는 기술로, 직접 SQL을 작성해야 하지만 JPA의 복잡성을 피할 수 있는 장점이 있다.

  • 예제 코드 (Spring Data JDBC Repository)
@Repository
public interface UserRepository extends CrudRepository<User, Long> {
    @Query("SELECT * FROM users WHERE email = :email")
    List<User> findByEmail(@Param("email") String email);
}

7. Microservices

7.1 Spring Cloud Gateway

Spring Cloud Gateway는 Spring Boot 기반의 API Gateway 솔루션으로, 마이크로서비스 아키텍처에서 클라이언트의 요청을 적절한 서비스로 라우팅하고 필터링하는 역할을 한다. 이는 Netflix Zuul의 대체 기술로 설계되었으며, 동적 라우팅, 보안, 부하 분산, API 모니터링, 로깅, 인증 등의 기능을 제공한다.

7.1.1 Spring Cloud Gateway 설정

@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }
}

7.1.2 application.yml 설정 예제

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/users/**
          filters:
            - RewritePath=/users/(?<segment>.*), /$<segment>

위 설정은 /users/** 경로로 들어오는 모든 요청을 USER-SERVICE로 전달하며, URL 재작성도 수행한다.


7.2 Cloud Config

Spring Cloud Config는 분산 환경에서 설정을 중앙 집중식으로 관리하는 프레임워크이다. 마이크로서비스의 설정 값을 외부 저장소(Git, JDBC, File System 등)에서 관리할 수 있으며, 애플리케이션이 실행 중에도 설정을 동적으로 변경할 수 있다.

7.2.1 Config Server 설정

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

7.2.2 application.yml 설정

server:
  port: 8888
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your-repo/config-repo

클라이언트 애플리케이션은 bootstrap.yml에서 spring.config.import를 사용하여 설정을 가져온다.

spring:
  config:
    import: 'optional:configserver:http://localhost:8888/'

7.3 Spring Cloud Circuit Breaker

Circuit Breaker(회로 차단기)는 장애 발생 시 서비스가 연쇄적으로 실패하는 것을 방지하는 패턴이다. Spring Cloud에서는 Resilience4j를 통해 Circuit Breaker 기능을 제공하며, 실패한 요청을 자동으로 감지하고 대체(fallback) 처리를 수행할 수 있다.

7.3.1 Circuit Breaker 적용

@CircuitBreaker(name = "userService", fallbackMethod = "fallbackGetUser")
public String getUser(String userId) {
    return restTemplate.getForObject("http://USER-SERVICE/users/" + userId, String.class);
}

public String fallbackGetUser(String userId, Throwable throwable) {
    return "Fallback response for user: " + userId;
}

7.4 Spring Cloud OpenFeign

Spring Cloud OpenFeign은 HTTP 요청을 인터페이스 기반으로 선언적으로 정의할 수 있는 클라이언트 라이브러리이다. Feign을 사용하면 RESTful API 호출을 위한 코드의 복잡도를 줄이고, 로드 밸런싱 및 오류 처리 기능을 쉽게 적용할 수 있다.

7.4.1 Feign Client 설정

@FeignClient(name = "user-service")
public interface UserClient {
    @GetMapping("/users/{id}")
    User getUserById(@PathVariable("id") String id);
}

7.5 Sleuth

Spring Cloud Sleuth는 분산 환경에서 마이크로서비스 간의 호출을 추적하는 기능을 제공한다. 이러한 추적 정보를 기반으로 Zipkin과 같은 도구를 활용하여 성능 분석 및 장애 진단이 가능하다.

7.5.1 Sleuth 설정

spring:
  zipkin:
    base-url: http://localhost:9411
  sleuth:
    sampler:
      probability: 1.0

7.6 Eureka

Eureka는 Netflix에서 개발한 서비스 레지스트리 및 디스커버리 서버이다. 마이크로서비스 환경에서 각 서비스가 동적으로 등록 및 검색될 수 있도록 하며, 부하 분산 및 장애 감지 기능도 제공한다.

7.6.1 Eureka Server 설정

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

7.6.2 Eureka Client 설정

spring:
  application:
    name: user-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

8. Spring MVC

Spring MVC (Model-View-Controller)는 Spring Framework에서 제공하는 웹 애플리케이션 개발을 위한 모듈입니다. 웹 애플리케이션을 설계할 때, 요청을 효과적으로 처리하고 응답을 반환하는 패턴을 제공합니다. 이를 통해 웹 개발을 효율적이고 유지보수하기 쉽게 만들 수 있습니다.

Spring MVC의 핵심 구성 요소:

  • DispatcherServlet: 클라이언트 요청을 받아 컨트롤러로 전달하는 프론트 컨트롤러 역할

  • Controller: 비즈니스 로직을 처리하고 데이터를 View로 전달

  • Model: 애플리케이션의 데이터 및 비즈니스 로직을 담당

  • View: 클라이언트에게 데이터를 표시하는 역할 (JSP, Thymeleaf 등)

  • 예제 코드 (Spring Boot + Spring MVC)

  1. 프로젝트 설정 (Spring Boot 기반)
<!-- pom.xml -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
  1. Controller 구현
@RestController
@RequestMapping("/api")
public class HelloController {

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, Spring MVC!";
    }
}
  1. 실행 및 테스트
$ mvn spring-boot:run

브라우저에서 http://localhost:8080/api/hello로 접속하면 Hello, Spring MVC!가 출력됩니다.


8.1 Servlet

Servlet은 Java를 기반으로 한 웹 애플리케이션 개발의 핵심 구성 요소입니다. Spring MVC는 기본적으로 서블릿을 활용하여 요청을 처리합니다.

Servlet 동작 방식

  1. 클라이언트가 요청을 보냄 (HTTP 요청)
  2. 웹 컨테이너(Tomcat 등)가 요청을 DispatcherServlet에게 전달
  3. DispatcherServlet이 요청을 적절한 컨트롤러로 위임
  4. 컨트롤러에서 비즈니스 로직을 수행 후 View를 반환
  5. View가 렌더링되어 클라이언트에게 응답됨

Servlet 예제 코드

@WebServlet("/hello-servlet")
public class HelloServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello, Servlet!</h1>");
    }
}

위 코드를 실행하고 브라우저에서 http://localhost:8080/hello-servlet로 접속하면 Hello, Servlet!이 출력됩니다.


8.2 JSP Files

JSP (JavaServer Pages)는 동적인 웹 페이지를 만들기 위한 기술입니다. Spring MVC에서 View를 렌더링하는 데 사용할 수 있습니다.

JSP 파일 설정

  1. src/main/webapp/WEB-INF/views/hello.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <title>JSP Example</title>
</head>
<body>
    <h1>${message}</h1>
</body>
</html>
  1. Controller에서 JSP에 데이터 전달
@Controller
@RequestMapping("/view")
public class JspController {

    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("message", "Hello, JSP!");
        return "hello"; // ViewResolver에 의해 hello.jsp로 매핑
    }
}
  1. application.properties에 ViewResolver 설정 추가
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

브라우저에서 http://localhost:8080/view/hello로 접속하면 Hello, JSP!가 출력됩니다.


8.3 Architecture

Spring MVC의 아키텍처는 다음과 같이 동작합니다.

  1. 클라이언트가 HTTP 요청을 보냄
  2. DispatcherServlet이 요청을 받아 적절한 컨트롤러로 전달
  3. 컨트롤러가 요청을 처리하고 Model을 생성
  4. ModelView에 전달됨
  5. ViewResolver가 적절한 View를 선택하여 클라이언트에게 반환

8.4 Components

Spring MVC에서 주요한 구성 요소는 다음과 같습니다.

  1. DispatcherServlet: 요청을 컨트롤러로 전달하는 핵심 서블릿
  2. Controller: 클라이언트 요청을 처리하고 적절한 데이터를 반환
  3. Model: View에서 사용할 데이터를 담는 객체
  4. ViewResolver: 적절한 View를 찾아주는 역할
  5. Service: 비즈니스 로직을 담당하는 계층
  6. Repository: 데이터베이스와의 연결을 담당하는 계층

Service 및 Repository 예제

    1. Service 계층
@Service
public class UserService {
    public String getUser() {
        return "John Doe";
    }
}
    1. Repository 계층
@Repository
public class UserRepository {
    public String findUser() {
        return "Database User: John Doe";
    }
}
    1. Controller에서 Service 사용
@Controller
@RequestMapping("/user")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/name")
    @ResponseBody
    public String getUserName() {
        return userService.getUser();
    }
}
Previous
spring boot