Spring Boot Configuration 설정

최민길(Gale)·2023년 1월 13일
1

안녕하세요 오늘은 Spring Boot Configuration 설정 방법에 대해 포스팅해보겠습니다.



위의 코드를 보시면 빨간 줄로 " 자동 주입을 할 수 없습니다. 해당 타입의 bean을 찾을 수 없습니다. " 과 같은 문구가 나옵니다. 하지만 실제 프로그램을 실행시켰을 때 이상 없이 잘 동작해서 넘어갔는데 왜 자동 주입이 되지 않았는지 궁금해서 원인을 찾아보았습니다.

자료 조사 결과, 해당 오류를 잡기 위해선 해당 객체에 Bean을 수동으로 주입해야한다고 합니다. 즉, @Configuration 어노테이션을 활용하여 위의 객체들에 Bean을 수동으로 주입하는 과정을 추가해야 합니다. @Configuration 어노테이션은 @ComponentScan이 처리될 때 자기 자신과 이 클래스에 @Bean으로 설정된 모든 객체의 초기화를 진행하여 해당 객체를 사용 시 Bean이 주입됩니다.

package com.example.test.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

@Configuration
@EnableJdbcRepositories
public class JdbcConfig extends AbstractJdbcConfiguration {

    @Value("${spring.datasource.driverClassName}")
    public String driverClassName;

    @Value("${spring.datasource.url}")
    public String url;

    @Value("${spring.datasource.username}")
    public String username;

    @Value("${spring.datasource.password}")
    public String password;

    // 접근할 DB 정의
    @Bean
    public DataSource dataSource() {
        DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName(driverClassName);
        dataSourceBuilder.url(url);
        dataSourceBuilder.username(username);
        dataSourceBuilder.password(password);
        return dataSourceBuilder.build();
    }

    // 사용할 JdbcTemplate에 대해서 정의 진행
    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(dataSource());
    }
}

따라서 공식 문서와 다른 블로그들을 통해 JdbcConfig 클래스를 생성했습니다. 우선 Datasource 객체를 이용하여 application.properties 내에 존재하는 DB 설정값을을 가져와 접근할 DB 정보를 매핑합니다. 이 후 JdbcTemplate 객체를 생성 후 해당 Datasource 객체를 파라미터로 넣어 리턴합니다. 이 때 각 객체 위에 @Bean 어노테이션을 붙이고 @Configuration 어노테이션과 JDBC 리포지토리에 접근 가능하도록 하는 @EnableJdbcRepositories 어노테이션도 같이 추가합니다.

그 결과 이전에 발생했던 오류가 발생하지 않는 것을 확인할 수 있습니다.

테스트 진행 시 정상적으로 잘 작동합니다.

package com.example.test.controller;

import com.example.test.model.request.InsertUserRequestDTO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(SpringExtension.class)
//@ContextConfiguration(classes = SecurityConfig.class)
@WebAppConfiguration
@SpringBootTest
class UserControllerTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @BeforeEach
    public void setup() {
        mvc = MockMvcBuilders
                .webAppContextSetup(context)
//                .apply(springSecurity())
                .build();
    }

    @Test
    public void getUserInfoTest() throws Exception{
        mvc.perform(get("/user/1"))
                .andExpect(status().isOk());
    }
}

다음 코드는 MockMvc 객체에 Bean 주입을 위한 코드 수정입니다. Spring Security 공식 홈페이지의 코드를 수정한 것으로 핵심적인 부분은 기존의 @AutoConfigureMockMvc 어노테이션을 통해 MockMvc 객체에 @Autowired를 하여 Bean을 직접 주입한 방식에서 @WebAppConfiguration 어노테이션을 이용하여 WebApplicationContext 객체를 @Autowired한 후 MockMvc 객체를 만들고 setup 메소드를 이용하여 WebApplicationContext 값을 추가해 빌드합니다. 주석 처리한 부분을 해제하면 Spring Security에서 사용 가능하다고 하는데 이 부분은 다음 포스팅 때 같이 설명드리겠습니다.

공식 문서에 MockMvcBuilder 설명을 보면 DispathcerServlet이 WebApplicationContext를 사용하여 Infrastructure와 application controller를 검색합니다. 따라서 현재 application controller의 정보를 MockMvc 객체에 추가하여 빌드하기 때문에 정상적으로 Bean 객체가 주입될 것이라고 유추해볼 수 있습니다.

이를 통해 Bean 자동 주입 오류가 발생하지 않는 것을 확인할 수 있으며

테스트 역시 성공적으로 통과했습니다. 그럼 이상으로 오늘의 포스팅 마치도록 하겠습니다!

profile
저는 상황에 맞는 최적의 솔루션을 깊고 정확한 개념의 이해를 통한 다양한 방식으로 해결해오면서 지난 3년 동안 신규 서비스를 20만 회원 서비스로 성장시킨 Software Developer 최민길입니다.

0개의 댓글