Spring

[Spring] Spring 핵심 개념 정리

beginner-in-coding 2025. 3. 8. 12:16

1. Spring 기본 개념

Q1. Spring 프레임워크란 무엇인가요?

Spring은 자바 기반의 엔터프라이즈 애플리케이션(Enterprise Application) 개발을 위한 프레임워크로, 객체 지향 프로그래밍을 지원하고, DI(의존성 주입)와 AOP(관점 지향 프로그래밍) 등의 개념을 통해 효율적인 개발을 가능하게 합니다.

 

Q2. Spring의 핵심 개념은 무엇인가요?

Spring의 핵심 개념은 다음과 같습니다.

  1. DI (Dependency Injection, 의존성 주입)
    • 객체 간의 의존성을 Spring 컨테이너가 관리하여 유연한 애플리케이션을 만들 수 있도록 합니다.
  2. AOP (Aspect Oriented Programming, 관점 지향 프로그래밍)
    • 로그, 트랜잭션, 보안과 같은 공통 기능을 분리하여 코드의 중복을 줄입니다.
  3. IoC (Inversion of Control, 제어의 역전)
    • 객체의 생성과 생명 주기를 개발자가 아니라 Spring 컨테이너가 관리합니다.
  4. POJO (Plain Old Java Object)
    • Spring은 일반적인 자바 객체(POJO) 기반으로 동작하여 기존 코드의 재사용성을 높입니다.
  5. Spring 컨테이너
    • Bean 객체를 생성하고 관리하는 역할을 합니다.

2. MVC 구조

Q3. Spring MVC 구조를 설명해주세요.

Spring MVC는 Model, View, Controller로 구성된 웹 애플리케이션 아키텍처입니다.

  1. Model: 데이터 및 비즈니스 로직을 처리합니다.
  2. View: 사용자에게 화면을 렌더링합니다. (Thymeleaf, JSP 등)
  3. Controller: 클라이언트의 요청을 받아 Model과 View를 연결하는 역할을 합니다.

요청 처리 흐름

  1. 클라이언트가 요청을 보냄 → DispatcherServlet이 요청을 받음
  2. HandlerMapping을 통해 적절한 Controller를 찾음
  3. Controller가 요청을 처리하고 Model을 반환함
  4. ViewResolver가 View를 찾아 응답을 반환함

3. 컨트롤러와 요청 처리

Q4. Spring에서 Controller는 어떻게 동작하나요?

Spring에서 컨트롤러는 @Controller 또는 @RestController 어노테이션을 사용하여 요청을 처리합니다.

@Controller
@RequestMapping("/user")
public class UserController {

    @GetMapping("/{id}")
    public String getUser(@PathVariable Long id, Model model) {
        model.addAttribute("user", userService.getUserById(id));
        return "userDetail";  // userDetail.html 반환
    }
}
  • @GetMapping("/{id}") → GET /user/{id} 요청을 처리
  • Model을 통해 데이터를 View로 전달

4. JSON 응답

Q5. Spring에서 JSON 응답을 반환하는 방법은?

Spring에서는 @RestController 또는 @ResponseBody를 사용하여 JSON 데이터를 반환할 수 있습니다.

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

    @GetMapping("/user/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }
}
  • @RestController는 @Controller + @ResponseBody를 포함하여 JSON 데이터를 자동으로 변환합니다.
  • ResponseEntity.ok(user)를 사용하면 HTTP 상태 코드와 함께 응답을 반환할 수 있습니다.

5. MyBatis SQL 연동

Q6. MyBatis란 무엇인가요?

MyBatis는 SQL을 XML 또는 어노테이션으로 관리하면서, 객체와 데이터베이스 간의 매핑을 쉽게 해주는 프레임워크입니다.

Q7. MyBatis에서 Mapper를 사용하는 방법은?

1) MyBatis Mapper 인터페이스

@Mapper
public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(Long id);
}

2) XML 기반 Mapper

<mapper namespace="com.example.mapper.UserMapper">
    <select id="getUserById" resultType="User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>

6. 예외 처리

Q8. Spring에서 전역 예외 처리는 어떻게 하나요?

@ControllerAdvice와 @ExceptionHandler를 사용하여 전역적으로 예외를 처리할 수 있습니다.

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(EntityNotFoundException.class)
    public ResponseEntity<String> handleEntityNotFoundException(EntityNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }
}
  • @RestControllerAdvice → 모든 컨트롤러에서 발생하는 예외를 처리
  • @ExceptionHandler(EntityNotFoundException.class) → 특정 예외를 처리

7. 페이징

Q9. Spring에서 페이징을 구현하는 방법은?

Spring Data JPA의 Pageable을 사용하면 간단하게 페이징을 구현할 수 있습니다.

 
public interface UserRepository extends JpaRepository<User, Long> {
    Page<User> findAll(Pageable pageable);
}

컨트롤러에서 사용

@GetMapping("/users")
public ResponseEntity<Page<User>> getUsers(@PageableDefault(size = 10) Pageable pageable) {
    Page<User> users = userService.getAllUsers(pageable);
    return ResponseEntity.ok(users);
}
 
  • Pageable을 사용하여 자동으로 페이지 처리가 가능합니다.
  • @PageableDefault(size = 10) → 기본적으로 10개씩 조회

8. 게시판 CRUD 구현

Q10. 게시판의 CRUD 기능을 구현하는 방법은?

1) 게시글 엔티티

@Entity
public class Post {
    @Id @GeneratedValue
    private Long id;
    private String title;
    private String content;
}

2) Repository

public interface PostRepository extends JpaRepository<Post, Long> {}

3) 서비스

@Service
public class PostService {
    @Autowired private PostRepository postRepository;

    public Post createPost(Post post) {
        return postRepository.save(post);
    }

    public List<Post> getAllPosts() {
        return postRepository.findAll();
    }
}

4) 컨트롤러

@RestController
@RequestMapping("/posts")
public class PostController {

    @Autowired private PostService postService;

    @PostMapping
    public ResponseEntity<Post> createPost(@RequestBody Post post) {
        return ResponseEntity.ok(postService.createPost(post));
    }

    @GetMapping
    public ResponseEntity<List<Post>> getAllPosts() {
        return ResponseEntity.ok(postService.getAllPosts());
    }
}
  • @PostMapping → 게시글 등록
  • @GetMapping → 게시글 목록 조회

1. Spring Boot 관련 질문

Q1. Spring과 Spring Boot의 차이점은 무엇인가요?

Spring Boot는 Spring 프레임워크를 더 쉽게 사용할 수 있도록 자동 설정(Auto Configuration) 기능을 제공하는 프레임워크입니다.

 

Spring vs Spring Boot

설정 방식 수동 설정(XML, Java Config) 필요 자동 설정 제공 (@SpringBootApplication)
내장 서버 별도 설정 필요 (Tomcat, Jetty 등) 내장 서버 지원 (Tomcat 기본 제공)
빌드 및 배포 WAR 파일로 배포 단독 실행 가능한 JAR 파일 지원
의존성 관리 수동으로 추가 spring-boot-starter-* 로 간편 관리

Q2. Spring Boot에서 @SpringBootApplication은 어떤 역할을 하나요?

@SpringBootApplication은 3가지 어노테이션을 포함한 복합 어노테이션입니다.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {}
  • @SpringBootConfiguration → @Configuration을 포함하며 설정 클래스로 사용
  • @EnableAutoConfiguration → Spring Boot의 자동 설정을 활성화
  • @ComponentScan → 현재 패키지와 하위 패키지를 자동으로 스캔하여 Bean을 등록

2. Spring Container와 Bean

Q3. Spring Container란 무엇인가요?

Spring Container는 Bean(객체)을 생성하고 관리하는 역할을 합니다.
주요 컨테이너는 다음과 같습니다.

  • ApplicationContext → 대부분의 Spring 애플리케이션에서 사용 (빈 라이프사이클, AOP, 국제화 지원)
  • BeanFactory → 기본적인 DI 컨테이너 (경량 컨테이너)

Q4. Spring Bean이란 무엇인가요?

Spring에서 관리하는 객체를 Bean이라고 하며, @Component 또는 @Bean 어노테이션으로 등록할 수 있습니다.

Bean 등록 방식

  1. 어노테이션 기반 (@Component, @Service, @Repository)
@Component
public class MyComponent {}
  1. Java Config 기반 (@Bean)
@Configuration
public class AppConfig {
    @Bean
    public MyComponent myComponent() {
        return new MyComponent();
    }
}
 
  1. XML 기반
<bean id="myComponent" class="com.example.MyComponent"/>

3. 의존성 주입(DI) 관련 질문

Q5. 의존성 주입(DI)이란 무엇인가요?

DI(Dependency Injection)란 객체의 의존성을 개발자가 아닌 Spring 컨테이너가 관리하는 방식을 의미합니다.

DI 방법

  1. 생성자 주입 (권장)
@Component
public class UserService {
    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}
  1. Setter 주입
@Component
public class UserService {
    private UserRepository userRepository;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}
 
  1. 필드 주입 (권장하지 않음)
@Component
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

4. AOP (Aspect Oriented Programming, 관점 지향 프로그래밍)

Q6. AOP란 무엇인가요?

AOP는 공통 기능(로깅, 트랜잭션, 보안 등)을 분리하여 코드 중복을 줄이는 방법론입니다.

AOP 주요 개념

  • Advice → 실행할 코드 (메서드 실행 전/후 등)
  • JoinPoint → Advice가 적용될 수 있는 지점 (메서드 실행, 예외 발생 등)
  • Pointcut → 실제 Advice가 적용되는 구체적인 위치
  • Aspect → 여러 Advice와 Pointcut을 묶어 관리

AOP 적용 예제

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBeforeMethod(JoinPoint joinPoint) {
        System.out.println("Method called: " + joinPoint.getSignature());
    }
}

 


5. 트랜잭션 관리

Q7. Spring에서 트랜잭션을 관리하는 방법은?

Spring은 @Transactional을 사용하여 트랜잭션을 관리할 수 있습니다.

@Service
public class OrderService {

    @Transactional
    public void placeOrder(Long orderId) {
        orderRepository.updateOrder(orderId);
        paymentRepository.processPayment(orderId);
    }
}
  • @Transactional을 메서드에 적용하면 DB 작업이 모두 성공해야만 커밋됩니다.
  • 예외 발생 시 자동으로 롤백됩니다.

6. Spring Security

Q8. Spring Security란 무엇인가요?

Spring Security는 Spring 기반 애플리케이션의 인증(Authentication)과 인가(Authorization)를 제공하는 프레임워크입니다.

Spring Security 핵심 개념

  • Authentication (인증) → 사용자의 신원을 확인 (로그인)
  • Authorization (인가) → 사용자의 권한을 확인 (접근 제한)
  • FilterChain → 여러 개의 보안 필터가 요청을 처리
  • BCrypt → 비밀번호 암호화

Spring Security 설정 예제

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .requestMatchers("/user/**").authenticated()
                .anyRequest().permitAll())
            .formLogin(Customizer.withDefaults());

        return http.build();
    }
}

7. Spring에서 캐시 적용

Q9. Spring에서 캐시(Cache)를 적용하는 방법은?

Spring은 @Cacheable 어노테이션을 사용하여 캐싱을 쉽게 적용할 수 있습니다.

예제: 캐시 적용

@Service
public class ProductService {

    @Cacheable("products")
    public Product getProduct(Long id) {
        return productRepository.findById(id).orElseThrow();
    }
}
  • @Cacheable("products") → 캐시에 저장된 데이터를 반환 (없으면 DB 조회 후 저장)
  • @CacheEvict("products") → 캐시 제거

8. Spring에서 이벤트 처리

Q10. Spring에서 이벤트를 처리하는 방법은?

Spring에서는 이벤트 기반 프로그래밍을 지원합니다.

이벤트 생성

public class UserCreatedEvent extends ApplicationEvent {
    public UserCreatedEvent(Object source) {
        super(source);
    }
}

이벤트 발행

@Autowired private ApplicationEventPublisher eventPublisher;

public void createUser(User user) {
    userRepository.save(user);
    eventPublisher.publishEvent(new UserCreatedEvent(this));
}

이벤트 리스너

@Component
public class UserCreatedListener {
    @EventListener
    public void handleUserCreated(UserCreatedEvent event) {
        System.out.println("User created event received!");
    }
}

'Spring' 카테고리의 다른 글

[Spring] 원격 프로그램의 실행  (0) 2025.03.04
[Spring] Spring 시작하기 전에  (3) 2025.02.11