Spring Boot Tutorial

1. Spring Boot 소개

1.1. Spring Framework와의 차이점

Spring Boot = Spring Framework + Default Configuration + Launcher + Plugins + Sever

Spring Framework가 유연한 설정과 확장이 장점인 반면, 설정 하는 방법을 익히는데 시간이 너무 걸리는 단점이 있음.

Spring Boot는 일반적으로 사용될만한 기본 설정을 제공하고, 이를 바로 실행 시킬수 있는 런처를 제공. 이를 위한 다수의 플러그인들도 제공 하여 빠른 시간안에 개발이 가능하게 함.

설정 커스터마이징을 통해 Spring Framework의 기능을 모두 사용할수 있음. 엔터프라이즈급 어플리케이션도 개발 가능.

2. 설치

Spring Boot는 2.0 부터 JDK 1.8 이상만 지원합니다.

2.1. Gradle 설치

의존성 관리및 빌드 도구로 maven과 gradle을 사용할수 있습니다. 여기에서는 gradle을 이용해서 투토리얼을 진행합니다.

2.1.1. Download

https://gradle.org/install/ 에서 최신 버전 다운로드 받기

현재 최신 버전은 5.1

2.1.2. 설치

적당한 위치에 풀어 넣는다.

추천위치: C:\java\util\gradle

경로 중간에 공백이 들어가지 않는 위치가 좋습니다.

사실 지금 내려 받은 gradle 은 딱 한번만 쓰일거라 어디에 두셔도 상관없습니다.

2.2. 프로젝트 설치

2.2.1. 프로젝트 폴더 만들기

이클립스는 workspace 부터 만들어야 함

mkdir workspace
mkdir workspace/MyProject

2.2.2. gradle init

gradle을 이용하여 프로젝트를 초기화 한다

/java/util/gradle/bin/gradle init

basic을 지정하여 초기화 한다.

폴더안에 .gradle, gradlew, gradlew.bat, build.gradle,settings.gradle 파일 및 폴더가 생성되었는지 확인한다.

2.2.3. build.gradle 수정

build.gradle 파일을 수정한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
buildscript {
  ext {
    springBootVersion = '2.1.2.RELEASE'
  }
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  }
}

plugins {
  // gradle 내장 플러그인
  id 'java'
  id 'war'
  id 'eclipse'
  id 'eclipse-wtp'
  id 'idea'

  // 다운로드해야 하는 플러그인. 버전 지정이 필요
  id 'org.springframework.boot' version '2.1.2.RELEASE'
  id 'io.spring.dependency-management' version '1.0.6.RELEASE'
}


group = 'com.myproject'
version = '0.0.1-SNAPSHOT'

sourceCompatibility = '1.8'
targetCompatibility = '1.8'

task initSrc  {
  doLast {
    project.sourceSets*.allSource.srcDirTrees.flatten().dir.each { dir ->
      dir.mkdirs()
    }
  }
}

configurations {
  developmentOnly
  runtimeClasspath {
    extendsFrom developmentOnly
  }
}

dependencies {
  implementation      'org.apache.commons:commons-lang3:3.8.1'
  implementation      'org.apache.commons:commons-collections4:4.2'

  implementation      'org.springframework.boot:spring-boot-starter'
  testImplementation  'org.springframework.boot:spring-boot-starter-test'

  implementation      'org.springframework.boot:spring-boot-starter-web'
  implementation      'org.springframework.boot:spring-boot-starter-jdbc'


  developmentOnly     'org.springframework.boot:spring-boot-devtools'
  providedRuntime     'org.springframework.boot:spring-boot-starter-tomcat'
}

2.2.4. settings.gradle 만들기

1
rootProject.name = 'MyProject'

2.2.5. Wrapper 만들기

로컬에 설치된 gradle을 이용할수도 있지만 이후에는 gradle wrapper만 사용할 겁니다.

~/java/util/gradle-5.1.1/bin/gradle wrapper

만들어진 실행 파일을 실행해 봅니다. (gradle init 를 통해 프로젝트를 생성했다면 이미 만들어 져 있습니다.)

  • Linux: ./gradlew

  • Windows: gradlew.bat

실행하면 자동으로 gradle 배포판을 다운로드하여 실행가능한 환경을 만들어 줍니다. 설치는 ${HOME}/.gradle 에 진행됩니다.

2.3. Gralde Repository에 대한 간단한 이해

  • NOTE: 중요한 내용은 아닙니다. 참고만 하세요

gradle은 3개의 repository를 지정할수 있습니다.

  • project dependency repository

    작성한 코드(src 밑의 소스파일)을 빌드 하는데 필요한 의존성을 내려 받기 위한 저장소. repositories 로 지정합니다.

    1
    2
    3
    4
    5
    
    allproject {
      repositories {
        ...
      }
    }

    또는 단일 프로젝트일때

    1
    2
    3
    
    repositories {
      ...
    }
  • script build dependency repository

    build.gradle 도 groovy 소스 파일이며 이 파일을 컴파일 할때 필요한 의존성을 내려 받기 위한 저장소. build.gradle 파일 최상단에 선언 되어야 합니다.

    1
    2
    3
    4
    5
    
    buildscript {
      repositories {
        ...
      }
    }
  • plugin dependency repository

    gradle 플러그인을 내려 받기 위한 저장소. settings.gradle 의 최상단에 선언되어야 합니다.

    1
    2
    3
    4
    5
    
    pluginManagement {
        repositories {
            ...
        }
    }

2.3.1. IDE 관련 Task 설정

  • ./gradlew initSrc 를 실행하여 src 폴더 생성

  • Eclipse: ./gradlew cleanEclipse eclipse 를 실행하여 .project 파일이 생성되는 것을 확인

  • IntelliJ: ./gradlew cleanIdea idea 를 실행하여 MyProject.ipr 파일이 생성되는 것을 확인

2.3.2. IDE로 프로젝트 띄우기

  • Eclipse: /workspace 를 연다

  • IntelliJ: /workspace/MyProject/MyProject.ipr 을 연다

3. 개발 시작

3.1. Main 만들기

  • src/main/java/com/myproject 패키지 만들기

  • MyProjectMain.java 만들기

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    package com.myproject;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class MyProjectMain {
            public static void main(String[] args) {
                    SpringApplication.run(MyProjectMain.class, args);
            }
    }

@SpringBootApplication = @EnableAutoConfiguration + @ComponentScan + @SpringBootConfiguration

  • @EnableAutoConfiguration: 클래스 패스에 포함된 라이브러리를 검사하여 적절한 설정을 자동으로 활성화

  • @ComponentScan: SpringApplication.run 에 넘겨준 Main Configuration 클래스 이하 경로의 Component를 Scan

  • @SpringBootConfiguration: @Configuration 과 마찬가지로 설정이 기술되는 클래스라는 표기(Marker)

3.2. application.properties 파일 만들기

  • src/main/resources/application.properties 파일 만들기

지금은 아무런 내용이 없어도 됩니다. 없으면 모두 기본 설정으로 동작함.

3.3. Controller 만들기

  • src/main/java/com/myproject/controller 패키지 만들기

  • ExampleController.java 만들기

4. 실행해보기

4.1. IDE에서 실행

IDE에서 MyProjectMain을 실행합니다.

4.2. gradle로 실행

./gradlew bootRun

4.3. 실행가능한 jar 로 실행

./gradlew bootJar

build/libs 폴더를 확인하면 MyProject-0.0.1-SNAPSHOT.jar 파일이 만들어져 있습니다. 다음과 같이 실행할수 있습니다.

java -jar MyProject-0.0.1-SNAPSHOT.jar

5. 여기 까지의 설정에 대한 시간을 더 단축하고 싶다면

https://start.spring.io 에서 기본 설정되어 있는 압축파일을 내려 받아 바로 개발 시작 할수 있음

6. 추가 설정

이 이후 부터는 기본적인 추가 설정입니다.

6.1. MyBatis 사용하기

6.1.1. 의존성 추가하기

build.gradle 에 다음 내용을 추가합니다.

1
2
3
4
5
6
7
8
9
10
...

dependencies {
  ...
  implementation     'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2'
  testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:1.3.2'

  implementation 'org.hsqldb:hsqldb' // 빠른 테스트를 위한 In-Memory DB
  ...
}

./gradlew eclipse 를 실행하여 의존성을 내려 받음.

6.1.2. 설정 추가

MyProjectMain 에 @MapperScan 설정을 추가한다.

1
2
3
4
5
6
7
...
import org.mybatis.spring.annotation.MapperScan;

@SpringBootApplication
@MapperScan(basePackageClasses=MyProjectMain.class)
public class MyProjectMain {
...

MyProjectMain 이하 하위 패키지의 클래스들중 `@Mapper`가 붙은 클래스를 찾아 Mapper로 등록하게 된다.

6.2. Mapper 추가

  • src/main/java/com/myproject/mapper 패키지 생성

  • ExampleMapper.java 파일 생성

    1
    2
    3
    4
    5
    6
    7
    8
    
    package com.myproject.mapper;
    
    import org.apache.ibatis.annotations.Mapper;
    
    @Mapper
    public interface ExampleMapper {
            String selectFromDB();
    }

6.2.1. SQL XML 추가

  • src/main/resources/com/myproject/mapper 패키지 생성

  • ExampleMapper.xml 파일 생성

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.myproject.mapper.ExampleMapper">
      <select id="selectFromDB" resultType="string">
    SELECT CURRENT_DATE AS today FROM (VALUES(0))
      </select>
    </mapper>

6.3. Controller 수정

ExampleController 수정

1
2
3
4
5
6
7
8
9
10
11
12
...

@RestController
public class ExampleController {
        @Autowired
        ExampleMapper exampleMapper;

        @RequestMapping("/")
        String home() {
                return "Hello World2! " + exampleMapper.selectFromDB();
        }
}

6.4. Mapper 와 SQL 파일을 같은 폴더에 두기

Mybatis의 장점은 Java소스와 SQL 소스를 분리해주는데 있다. 하지만 파일이 분리되는 것은 좋으나 maven 방식의 소스폴더 구조상 src/main/javasrc/main/resources 하위에 각기 java 파일과 xml 파일을 분리해두어 햐는 것 때문에 거리가 멀어지는 불편함이 있다.

이런 문제를 극복하기 위해 Mapper 와 SQL XML을 같은 폴더에 두고 볼수 있게 할수 있다.

  • 일단 ExampleMapper.xml 파일을 ExampleMaper.java 와 같은 폴더로 이동한다.

  • build.gradle 에 다음을 추가한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    sourceSets {
        main {
            resources {
                srcDirs = ["src/main/resources","src/main/java"]
                includes = ["**/*"]
                excludes = ["**/*.java"]
            }
        }
    }

    위의 설정을 통해 resouce 처리 과정에서 기본 폴더인 src/main/resources 에 추가적으로 폴더를 지정해서 resource 처리를 할수 있다.

6.5. Lombok 사용하기

Lombok은 IDE용 플러그인은 lombok.jar 안에 포함하고 있지만 빌드 도구용 플러그인을 가지고 있지 않습니다. gradle용 플러그인을 설치할 필요가 있습니다.

build.gradle 에 다음 내용을 추가합니다.

1
2
3
4
5
6
7
8
9
10
11
12
...
plugins {
  ...
  id 'io.franzbecker.gradle-lombok' version '1.14'
  ...
}
...
lombok {
  version = "1.18.4"
  sha256 = ""
}
...

7. 자동 설정 변경 및 확장

우선은 @EnableAutoConfiguration 로 자동 설정된 설정을 변경하고 확장하는 방법에 대해 알아보자

7.1. Spring@MVC

Spring MVC의 자동 설정은 다음과 같은 내용을 포함한다.

  • ContentNegotiatingViewResolver and BeanNameViewResolver 빈 설정 포함

  • 정적 리소스 취급 지원. WebJars 역시 지원함

  • ConverterGenericConverter, Formatter 빈들을 자동 등록함

  • HttpMessageConverters 를 지원함

  • MessageCodeResolver 를 자동 등록함

  • 정적 index.html 지원

  • Favicon 지원

  • ConfigurableWebBindingInitializer 빈을 자동으로 사용

Spring Boot의 @MVC에 대한 자동설정을 유지한 상태에서 설정(인터셉터나 포메터등)을 추가 하고 싶다면 설정을 추가 하고 싶다면 @EnableWebMvc 어노테이션이 붙지 않은 @Configuration 클래스를 만들어서 설정하면 된다.
RequestMappingHandlerMapping, RequestMappingHandlerAdapter, ExceptionHandlerExceptionResolver 의 구현체를 변경하고 싶다면 WebMvcRegistrationsAdapter 를 등록하면 됩니다
만약 Spring @MVC에 설정에 완전한 제어를 하고 싶다면 @EnableWebMvc 이 붙은 @Configuration 클래스를 만들어서 설정하면 된다. 즉 @EnableWebMvc 어노테이션은 자동 설정을 사용하지 않겠다는 선언인 셈이다. 주의 필요!!

7.1.1. HttpMessageConverters

HTTP 요청과 응답에 XML, JSON등 다양한 메시지를 다루기 위해 여러 HttpMessageConverter Bean 들이 자동 등록 되는데, 이 목록에 추가하거나 커스터마이징을 위한 메커니즘으로 HttpMessageConverters 를 등록할수 있다.

1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class MyConfiguration {

        @Bean
        public HttpMessageConverters customConverters() {
                HttpMessageConverter<?> additional = ...
                HttpMessageConverter<?> another = ...
                return new HttpMessageConverters(additional, another);
        }

}

application context에 등록된 모든 HttpMessageConverter Bean 은 위의 목록에 추가된다. 같은식으로 기본 등록되는 컨버터 들을 교체 할 수 있다.

7.1.2. 정적 컨텐츠 제공

기본적으로 다음 디렉토리에서 정적 컨텐츠를 찾아 제공하게 됩니다. (찾는 root 위치는 classpath 또는 ServletContext root 입니다.)

  • /static

  • /public

  • /resources

  • /META-INF/resources

7.1.3. Teplate Engine

Spring Boot는 FreeMarker, Groovy, Thymeleaf, Mustache, JSP등을 지원합니다.

JSP는 executable jar에서 지원되지 않기 때문에 가급적 사용하지 않는게 좋습니다.

템플릿 소스는 src/main/resources/templates 에 저장하면 됩니다.

여기서는 thymeleaf를 세팅해 봅니다

  1. build.gradle에 thymeleaf 의존성을 추가합니다.

    build.gradle
    1
    
    implementation      'org.springframework.boot:spring-boot-starter-thymeleaf'
  2. Controller 변경

    ExampleController.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    @Controller
    @Slf4j
    public class ExampleController {
            @GetMapping("/")
            public String home(Model model) {
                    model.addAttribute("message", "world");
                    return "greeting" ;
            }
    }
    Template을 사용하기 때문에 Controller가 @RestController 가 붙으면 안됩니다. 이걸로 삽질하는 경우가 꽤나 많습니다.
  3. 템플릿 파일은 src/main/resources/templates/greeting.html 에 생성합니다

    greeting.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
    <meta charset="utf-8" />
    </head>
    <body>
            <div th:text="'hello '+${message}">
    </body>
    </html>

7.1.4. Servlet Filter

web.xml 없이 서블릿을 등록해 봅니다.

샘플로 필터를 하나 만들어 봅니다.

MyFilter
1
2
3
4
5
6
7
8
9
10
@Slf4j
public class MyFilter implements Filter {

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                        throws IOException, ServletException {
                log.info("Requested");
                chain.doFilter(request, response);
        }
}

이걸 빈으로 등록합니다. 필터간의 우선순위는 Bean Order를 주면 됩니다.

MyConfiguration.java
1
2
3
4
5
6
7
8
@Configuration
public class MyConfiguration {
  @Order(0)
        @Bean
        public Filter myFilter() {
                return new MyFilter();
        }
}

이렇게 등록한 필터는 모든 요청에 대해 동작합니다. 일부 URL에 대해서만 동작하게 하고 싶다면 FilterRegistrationBean 으로 등록해야 합니다.

MyConfiguration.java
1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class MyConfiguration {
        @Order(0)
        @Bean
        public FilterRegistrationBean<MyFilter> loggingFilter() {
                FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
                registrationBean.setFilter(new MyFilter());
                registrationBean.addUrlPatterns("/user/*");
                return registrationBean;
        }
}

7.2. Spring Security

Spring Security를 사용하기 위해 의존성을 추가합니다.

build.gradle
1
implementation      'org.springframework.boot:spring-boot-starter-security'

Spring boot의 기본 security 설정은 다음을 제공합니다.

  • 메모리 기반으로 단일 유저 한명을 제공하는 UserDetailsService

  • Form-based login or HTTP Basic security

  • DefaultAuthenticationEventPublisher 빈 제공 (인증 이벤트 전파용)

물론 이것은 데모용 수준에 지나지 않기 때문에 커스터마이징을 해야 합니다.

그러기 위해선 일단 웹 어플리케이션 Security 기본 설정을 제거 해야 하는데 WebSecurityConfigurerAdapter 을 구현한 빈을 등록 하면 됩니다.

이 클래스에서는 상당히 많은 설정을 할수 있습니다.(해주어야 합니다)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
@Configuration
public class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
        @Autowired
        private LoginSuccessHandler loginSuccessHandler;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
                //@formatter:off
                http
                        .authorizeRequests()
                                .antMatchers("/api")         // api 로 가는 요청은
                                        .authenticated()         // 인증되어야 한다.
                                .anyRequest()                         //  그외  모든 요청은
                                        .permitAll()                 // 인증이 필요 없다.

                        .and()
                                .formLogin()
                                        .loginPage("/login")
                                        .loginProcessingUrl("/login")
                                        .failureUrl("/login?error=true")
                                        .successHandler(loginSuccessHandler)
                                        .usernameParameter("username")
                                        .passwordParameter("password")
                                        .permitAll()
                        .and()
                                .httpBasic()
                                        .disable() //  더이상 할게 없기 때문에  .and()  생략됨
                                .logout()
                                        .deleteCookies("remove")
                                        .invalidateHttpSession(true)
                                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                                        .logoutSuccessUrl("/")
                        .and()
                                .csrf()
                                        .disable();
                //@formatter:on
        }

        @Override
        public void configure(WebSecurity web) throws Exception {
                //@formatter:off
                web
                .ignoring()
                        .antMatchers("/resources/**")
                        .antMatchers("/static/**")
                ;
                //@formatter:on

        }

}

@Component
class LoginSuccessHandler implements AuthenticationSuccessHandler {

        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                        Authentication authentication) throws IOException, ServletException {
                response.setStatus(HttpServletResponse.SC_OK);
                response.sendRedirect("/");
        }

}

자세한 것은 Spring Security를 보세요

마찬가지로 기본 제공되는 UserDetailsService`를 비활성화 하려뎐 `UserDetailsService, AuthenticationProvider 빈을 등록하던가 AuthenticationManager 빈을 등록하면 됩니다. (모두 WebSecurityConfigurerAdapter 에서 오버라이딩 할수 있긴합니다.)

7.3. Spring Application

7.3.1. 설정 파일

Spring Boot의 설정은 매우 다양한 경로를 통해 결정됩니다. 우선순위는 다음과 같습니다.

  1. 홈 디렉토리에 위치한 Devtools 의 전역 설정 파일(~/.spring-boot-devtools.properties Devtool이 활성화 되었을때만 적용됨).

  2. 테스트에 어노테이션 된 @TestPropertySource

  3. @SpringBootTest 어노테이션이 붙은 테스트 코드의 properties 필드

  4. Command line arguments.

  5. 환경변수(Environment 또는 System)에 포함된 SPRING_APPLICATION_JSON 을 JSON 파싱한 Properties

  6. ServletConfig init parameters.

  7. ServletContext init parameters.

  8. java:comp/env JNDI 속성

  9. Java System properties (System.getProperties()).

  10. OS environment variables.

  11. Key가 random.*. 로 시작하는 경우 RandomValuePropertySource 에서 값을 읽어옴

  12. 외부 Profile-specific application properties 파일 (application-{profile}.properties and YAML variants).

  13. JAR 파일 내부 Profile-specific application properties(application-{profile}.properties and YAML variants).

  14. 외부 Application properties (application.properties and YAML variants).

  15. Jar 파일 내부 Application properties (application.properties and YAML variants).

  16. @Configuration 클래스에 기술된 @PropertySource.

  17. Spring Boot 기본 설정 (SpringApplication.setDefaultProperties 에 지정되어 있음).

application.properties 는 다음 위치에서 찾게 됩니다.

  1. 현재 디렉토리의 /config 하위 디렉토리

  2. 현재 디렉토리

  3. 클래스패스의 /config 패키지

  4. 클래스패스 루트

7.3.2. Logging

기본적으로 Spring Boot는 logback을 사용합니다.

logback은 classpath 루트에서 logback.xml,logback.groovy 를 순차적으로 찾아 발견 되는 파일을 설정 파일로 사용합니다. 보통의 경우라면 여기에 로그 설정을 하면 됩니다.

Spring Boot는 프로필 기반 설정, 환경변수 제공등 몇몇 유용한 logback 확장을 제공하는데, 스프링이 기동 되는 시점은 logback이 이미 logback.xml 을 읽어서 초기화가 된 이후가 됩니다.

이를 극복하기 위해 Spring Boot에서는 자체 설정된 logback.xml`을 제공하며, 여기에서 `logback-spring.xml,logback-spring.groovy 파일을 추가로 읽어와서 설정 파일로 사용합니다. 따라서 Spring Boot기반의 어플리케이션들은 logback-spring.xml 을 설정 파일로 사용하면 됩니다.

이를 통해 다음과 같은 확장 기능을 사용할수 있습니다.

logback-spring.xml
<springProfile name="staging">
        <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
        <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
        <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

7.3.3. Embedded Server

Embedded Server 사용하지 않기
application.properteis
spring.main.web-application-type=none
포트 변경

임베디드 서버의 포트를 지정하는 방식은 몇가지 있습니다.

  1. application.properteis

    server.port=8888
  2. WebServerFactoryCustomizer 구현한 빈 제공하기

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    @Component
    public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    
            @Override
            public void customize(ConfigurableServletWebServerFactory server) {
                    server.setPort(9000);
            }
    
    }

8. 기본 설정 제거 및 커스터마이징

@EnableAutoConfiguration 를 사용해도 자동 설정을 불가능하게 하고 완전히 커스터마이징 할수도 있다.

Tags: spring   spring boot   tutorial