Project/Team Project

스프링부트 프로젝트 - configuration 정리

깨구르르 2024. 5. 6. 17:46
728x90

현재 세 번째 프로젝트를 진행하고 있다.

스프링부트를 이용한 프로젝트인데, 필요한 설정 파일에 대해서 정리해보려고 한다.

 

1. CustomServletConfig

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class CustomServletConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/js/**")
                .addResourceLocations("classpath:/static/js/");
        registry.addResourceHandler("/images/**")
                .addResourceLocations("classpath:/static/images/");
        registry.addResourceHandler("/font/**")
                .addResourceLocations("classpath:/static/fonts/");
        registry.addResourceHandler("/css/**")
                .addResourceLocations("classpath:/static/css/");
        registry.addResourceHandler("/assets/**")
                .addResourceLocations("classpath:/static/assets/");
    }
}
  • @Configuration
    • 이 어노테이션이 붙은 클래스는 애플리케이션의 설정을 담당하는 클래스가 됨
    • Spring IoC 컨테이너에 의해 bean으로 관리됨
  • @EnableWebMvc
    • Spring MVC를 사용하는 애플리케이션에 필요한 기본 설정 활성화
    • Spring Framework에서 여러 Config 값을 알아서 세팅해줌
  • WebMvcConfigurer 인터페이스
    • Spring MVC의 구성 요소를 커스터마이징하기 위한 인터페이스
    • 정적 리소스를 어떻게 제어할지 구성할 수 있음
    • 리소스의 위치 등을 적절하게 설정해줄 수 있음
  • addResourceHandlers(ResourceHandlerRegistry registry)
    • 정적 자원에 대한 핸들러를 등록
    • 이 메서드를 오버라이드하여 정적 자원의 위치와 URL 패턴을 지정할 수 있음
  • registry.addResourceHandler("/js/**")
                    .addResourceLocations("classpath:/static/js/")
    • /js/** 패턴으로 요청이 들어오면 클래스에 있는 /static/js 디렉토리에서 자원을 찾도록 설정함
    • addResourceHandler: 메서드 요청 패턴을 정의함
    • addResourceLocations: 정적 리소스 파일이 위치한 경로를 정의함

 


 

2. RootConfig

import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RootConfig {

    @Bean
    public ModelMapper getMapper() {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration()
                .setFieldMatchingEnabled(true)
                .setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
                .setMatchingStrategy(MatchingStrategies.LOOSE);

        return modelMapper;
    }
}
  • @Configuration
  • @Bean
    • 해당 메서드가 Spring 컨테이너에 의해 관리되는 빈 객체를 반환
  • getMapper()
    • 이 메서드는 ModelMapper 인스턴스를 생성하고 반환
  • ModelMapper
    • Java 객체 간의 매핑을 단순화하는 데 사용되는 라이브러리
    • 두 객체 간의 필드 이름을 기반으로 한 매핑을 수행하는 ModelMapper를 설정함
    • Entity와 DTO간의 매핑을 단순화하기 위해서 사용됨
    • 복잡한 매핑 로직을 구현하는 대신 단순히 객체 간의 데이터 전환을 수행할 수 있음
  • modelMapper.getConfiguration()
    • ModelMapper의 설정을 가져옴
  • setFieldMatchingEnabled(true)
    • 매핑할 때 필드 이름을 사용하는 것을 활성화함
    • 필드 이름이 일치하는 경우에만 매핑이 수행됨
  • setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
    • 매핑할 때 필드에 대한 접근 수준을 지정
    • PRIVATE: private 필드에 접근할 수 있음. 대부분의 Entity 클래스의 필드는 private으로 정의되어 있으므로 대부분PRIVATE을 사용함
    • PROTECTED: protected 필드에 접근할 수 있음
    • PACKAGE_PRIVATE: 패키지 전용 필드에 접근할 수 있음
    • PUBLIC: public 필드에만 접근할 수 있음(기본값)
  • setMatchingStrategry(MatchingStrategies.LOOSE)
    • 매핑 전략을 지정함
    • STANDARD
      • 가장 일반적으로 사용됨
      • 정확한 필드 이름 일치가 필요함
      • 엔티티와 DTO의 필드 이름이 정확히 일치해야만 매핑이 이루어짐
    • STRICT
      • 대소문자 구분을 함
      • 정확한 필드 이름 일치가 필요함
      • 엔티티와 DTO의 필드 이름이 정확히 일치하고 대소문자도 일치해야만 매핑이 이루어짐
    • LOOSE
      • 대소문자 구분을 하지 않음
      • 필드 이름의 일부 일치만으로도 매핑을 수행함
      • 예) firstName 필드가 first_name으로 매핑될 수 있음
      • 느슨한 매칭을 사용해 필드 이름의 부분적인 일치를 허용함
    • STRICT_ORDER
      • 엔티티와 DTO의 필드 순서도 일치해야 함
      • 필드 이름뿐만 아니라 순서도 정확히 일치해야만 매핑이 이루어짐
    • LENIENT
      • 일치하는 필드가 없더라도 오류를 발생시키지 않음
      • 매핑할 수 있는 필드를 찾지 못해도 계속 진행함

 


 

3. SwaggerConfig

Swagger란 프론트엔드 개발자와 백엔드 개발자 간의 소통을 돕는 역할을 하는 도구이다.

Postman과 유사한데, Swagger는 프론트 개발자 입장에서 더 쉽게 API를 테스트할 수 있는 방식이라고 보면 된다.

Swagger를 사용하기 위해서는 Config 파일을 만드는 것뿐만 아니라,

build.gradle과 application.properties에도 설정을 해주어야 한다.

// build.gradle
dependencies {
	implementation 'io.springfox:springfox-swagger-ui:3.0.0'
}

//application.properties
swagger.port=사용할 swagger port 번호
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

@Configuration
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.OAS_30)
                .useDefaultResponseMessages(false)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.allrounders.goalkeeper"))
                .paths(PathSelectors.any())
                .build()
                .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("GoalKeeper Project Swager")
                .build();
    }
}
  • @Configuration
  • @Bean
    • 해당 메서드가 Spring 컨테이너에 의해 관리되는 빈 객체를 반환
    • 여기에서는 api()와 apiInfo() 메서드가 Bean으로 정의되어 있음
  • Docket 클래스
    • Swagger의 메인 설정을 나타내는 클래스
    • Docket 객체를 생성하여 API를 문서화하고 구성
  • api()
    • Swagger 문서의 주요 설정을 정의하는 메서드
    • API의 기본 응답 메시지를 비활성화함
    • API의 베이스 패키지를 지정하여 문서화할 API를 선택함
    • 모든 경로를 문서화 대상으로 선택하도록 설정함
    • apiInfo() 메서드를 호출하여 API 문서의 정보를 설정함
  • apiInfo()
    • API 문서에 표시될 정보를 정의하는 메서드
    • 위 코드에서는 API 문서의 제목을 설정함

 


 

4. QuerydslConfig

Querydsl은 HQL(Hibernate Query Language)의 쿼리를 타입에 안전하게 생성 및 관리해주는 프레임워크이다.

정적 타입을 이용하여 SQL과 같은 쿼리를 생성할 수 있게 해준다.

Querydsl이 궁금하다면 아래 글을 참고하자.

2024.04.19 - [Web/SpringBoot] - [SpringBoot] 쿼리 메소드 vs JPQL vs QueryDsl vs NativeQuery

Querydsl을 사용하기 위해는 Config 클래스를 작성하는 것뿐만 아니라,

build.gradle에 설정을 해주어야 한다.

// build.gradle
buildscript {
	ext {
		queryDslVersion = "5.0.0"
	}
}
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Configuration
public class QuerydslConfig {

    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(this.entityManager);
    }
}
  • @Configuration
  • @PersistenceContext
    • EntityManager를 주입하기 위해 사용됨
  • EntityManager
    • JPA에서 엔티티를 관리하고 영속성 컨텍스트를 제공하는 인터페이스
      • 영속성 컨텍스트❓
        - 엔티티 객체를 관리하는 환경
        - 엔티티의 상태를 추적하고 DB와의 데이터 동기화를 관리함
        - 트랜잭션 범위 내에서 동작함
        - 엔티티의 상태를 일관되게 유지
        👉 엔티티의 생명 주기를 관리하고 DB와의 상호 작용을 담당함
    • @PersistenceContext 어노테이션에 의해 주입됨
  • @Bean
    • 해당 메서드가 Spring 애플리케이션 컨텍스트에 빈으로 등록되어야 함
    • 이 메서드는 jpaQueryFactory()라는 이름의 빈을 생성하고 반환함
  • public JPAQueryFactory jpaQueryFactory()
    • JPAQueryFactory 인스턴스를 생성함
    • JPAQueryFactory?
      • Querydsl을 사용하여 JPA 쿼리를 생성하기 위한 핵심 클래스
      • JPA 기반의 데이터베이스와 상호 작용하기 위한 쿼리 생성을 담당함
      • EntityManager를 사용하여 JPA 쿼리를 실행하고, Querydsl이 제공하는 flent API를 통해 쿼리를 작성하고 실행함

👉 Querydsl을 사용하여 JPA 쿼리를 생성하기 위해 필요한 JPAQueryFactory 빈을 설정하는데 사용됨

 


 

결론

 

  • CustomServletConfig는 Spring MVC 프로젝트에서 정적 자원을 처리하기 위한 설정을 하는 클래스
  • RootConfig는 ModelMapper를 빈으로 등록하고 설정하여 Entity와 DTO간의 매핑을 단순화하는 클래스
  • SwaggerConfig는 Spring 애플리케이션에서 Swagger를 통해 API를 문서화하는 클래스
  • QuerydslConfigQuerydsl을 사용하여 JPA 쿼리를 생성하기 위해 필요한 JPAQueryFactory 빈을 설정하는데 사용

 

728x90