Как изменить порт spring boot

How do I configure the TCP/IP port listened on by a Spring Boot application, so it does not use the default port of 8080.

How do I configure the TCP/IP port listened on by a Spring Boot application, so it does not use the default port of 8080.

Tung's user avatar

Tung

1,5194 gold badges15 silver badges32 bronze badges

asked Jan 13, 2014 at 2:59

Paul Verest's user avatar

Paul VerestPaul Verest

58.3k47 gold badges197 silver badges323 bronze badges

4

As said in docs either set server.port as system property using command line option to jvm -Dserver.port=8090 or add application.properties in /src/main/resources/ with

server.port=8090

For a random port use:

server.port=0

Similarly add application.yml in /src/main/resources/ with:

server:
  port: 8090

blacktide's user avatar

blacktide

9,9707 gold badges32 silver badges51 bronze badges

answered Jan 13, 2014 at 3:14

Paul Verest's user avatar

Paul VerestPaul Verest

58.3k47 gold badges197 silver badges323 bronze badges

16

There are two main ways to change the port in the Embedded Tomcat in a Spring Boot Application.

Modify application.properties

First you can try the application.properties file in the /resources folder:

server.port = 8090

application.properties file

Modify a VM option

The second way, if you want to avoid modifying any files and checking in something that you only need on your local, you can use a vm arg:

Go to Run -> Edit Configurations -> VM options

-Dserver.port=8090

Change port with a vm arg

Additionally, if you need more information you can view the following blog post here: Changing the port on a Spring Boot Application

answered May 14, 2015 at 23:57

anataliocs's user avatar

1

Since Spring Boot provides various configuration externalization mechanism (through various PropertySource implementations and/or processors wired into Environment object in order), you can set any property outside of your jar archive through following methods:

  1. Pass property through command line argument as application argument

    java -jar <path/to/my/jar> --server.port=7788
    
  2. From property in SPRING_APPLICATION_JSON (Spring Boot 1.3.0+)

    • Define environment variable in U*IX shell:

      SPRING_APPLICATION_JSON='{"server.port":7788}' java -jar <path/to/my/jar>
      
    • By using Java system property:

      java -Dspring.application.json='{"server.port":7788}' -jar <path/to/my/jar>
      
    • Pass through command line argument:

      java -jar <path/to/my/jar> --spring.application.json='{"server.port":7788}'
      
  3. Define JVM system property

    java -Dserver.port=7788 -jar <path/to/my/jar>
    
  4. Define OS environment variable

    • U*IX Shell

      SERVER_PORT=7788 java -jar <path/to/my/jar>
      
    • Windows

      SET SERVER_PORT=7788
      java -jar <path/to/my/jar>
      
  5. Place property in ./config/application.properties configuration file

    server.port=7788
    

    and run:

     java -jar <path/to/my/jar>
    
  6. Place property in ./config/application.yaml

    server:
        port: 7788
    

    and run:

     java -jar <path/to/my/jar>
    
  7. Place property in ./application.properties

    server.port=7788
    

    and run:

     java -jar <path/to/my/jar>
    
  8. Place property in ./application.yaml

    server:
        port: 7788
    

    and run:

     java -jar <path/to/my/jar>
    

You can combine above methods all together, and the former configuration in the list take precedence over the latter one.

For example:

SERVER_PORT=2266 java -Dserver.port=5566 -jar <path/to/my/jar> --server.port=7788

The server will start and listen on port 7788.

This is very useful providing default properties in PropertySources with lower precedence (and usually packaged in the archive or coded in the source), and then override it in the runtime environment. And it is the design philosophy of Spring Boot:

Be opinionated out of the box, but get out of the way quickly as requirements start to diverge from the defaults.


SERVER_NAME to server.name conversion was done by Relaxed Binding.

answered Nov 29, 2016 at 17:39

tan9's user avatar

tan9tan9

3,3302 gold badges17 silver badges21 bronze badges

0

Also, you can configure the port programmatically.

For Spring Boot 2.x.x:

@Configuration
public class CustomContainer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
  public void customize(ConfigurableServletWebServerFactory factory){
    factory.setPort(8042);
  }
}

For older versions:

@Configuration
public class ServletConfig {
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return (container -> {
            container.setPort(8012);
        });
    }
}

Positive Navid's user avatar

answered Nov 3, 2015 at 18:29

makerj's user avatar

makerjmakerj

2,0992 gold badges18 silver badges27 bronze badges

8

If you would like to run it locally, use this —

mvn spring-boot:run -Drun.jvmArguments='-Dserver.port=8085'

As of Spring Boot 2.0, here’s the command that works (clues were here):

mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8085

Brent Bradburn's user avatar

answered Apr 15, 2016 at 23:00

itwarilal's user avatar

itwarilalitwarilal

1,2249 silver badges16 bronze badges

1

You can set port in java code:

HashMap<String, Object> props = new HashMap<>();
props.put("server.port", 9999);

new SpringApplicationBuilder()
    .sources(SampleController.class)                
    .properties(props)
    .run(args);

Or in application.yml:

server:
    port: 9999

Or in application.properties:

server.port=9999

Or as a command line parameter:

-Dserver.port=9999

answered Mar 17, 2016 at 16:58

ayurchuk's user avatar

ayurchukayurchuk

1,8291 gold badge15 silver badges13 bronze badges

2

In case you are using application.yml add the Following lines to it

server:
     port: 9000

and of course 0 for random port.

Paul Verest's user avatar

Paul Verest

58.3k47 gold badges197 silver badges323 bronze badges

answered Dec 3, 2014 at 19:30

gatolgaj's user avatar

gatolgajgatolgaj

1,1717 silver badges12 bronze badges

2

As explained in Spring documentation, there are several ways to do that:

Either you set the port in the command line (for example 8888)

-Dserver.port=8888 or --server.port=8888

Example : java -jar -Dserver.port=8888 test.jar

Or you set the port in the application.properties

server.port=${port:4588}

or (in application.yml with yaml syntax)

server:
   port: ${port:4588}

If the port passed by -Dport (or -Dserver.port) is set in command line then this port will be taken into account. If not, then the port will be 4588 by default.

If you want to enforce the port in properties file whatever the environment variable, you just have to write:

server.port=8888

answered Jan 21, 2017 at 13:21

OlivierTerrien's user avatar

OlivierTerrienOlivierTerrien

2,3611 gold badge19 silver badges31 bronze badges

Include below property in application.properties

server.port=8080

Derick Daniel's user avatar

answered Oct 18, 2016 at 18:22

Chandramouli's user avatar

1

When you need a programatically way of doing it, you can set it during startup:

System.getProperties().put( "server.port", 80 );
SpringApplication.run(App.class, args);

This might help for things like environment dependent port.
Have a nice day

answered Apr 3, 2016 at 16:21

Luis Mauricio's user avatar

2

if you are using gradle as the build tool, you can set the server port in your application.yml file as:

server:
  port: 8291

If you are using maven then the port can be set in your application.properties file as:

server.port: 8291

Gaurav Jeswani's user avatar

answered Oct 24, 2019 at 9:20

VSharma's user avatar

VSharmaVSharma

4714 silver badges8 bronze badges

2

To extend other answers:

There is a section in the docs for testing which explains how to configure the port on integration tests:

  • 41.3 Testing Spring Boot applications
  • 41.3.3 Working with random ports

At integration tests, the port configuration is made using the annotation @SpringBootTest and the webEnvironment values.


Random port:

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)

You can inject the value using @LocalServerPort which is the same as @Value("${local.server.port}").

  • Example:

Random port test configuration:

@RunWith(SpringRunner.class
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ExampleTest {
   ...
   @LocalServerPort //to inject port value
   int port;
}

Defined port:

@SpringBootTest(webEnvironment=WebEnvironment.DEFINED_PORT)

It takes the value from server.port if is defined.

  • If is defined using @TestPropertySource(properties = "server.port=9192"), it overrides other defined values.
  • If not, it takes the value from src/test/resources/application.properties (if exists).
  • And finally, if it is not defined it starts with the default 8080.

Example:

Defined port test configuration:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties = "server.port=9192")
public class DemoApplicationTests {

    @Test
    public void contextLoads() {
    }

}

andi's user avatar

andi

9311 gold badge12 silver badges17 bronze badges

answered May 29, 2017 at 18:40

Pau's user avatar

PauPau

14.3k13 gold badges64 silver badges90 bronze badges

You can specify port by overriding EmbeddedServletContainerFactory bean within your configuration (java based or xml). There you can specify port for used embedded servlet container. Please, see Spring Boot — Core «Embedded Servlet Container Support» paragraph and example there. Hope this helps.

Will's user avatar

Will

6,4613 gold badges32 silver badges41 bronze badges

answered Jan 13, 2014 at 10:20

nndru's user avatar

nndrunndru

2,03721 silver badges15 bronze badges

2

In application.properties file present in resources:

server.port=8082

FelixSFD's user avatar

FelixSFD

5,94210 gold badges46 silver badges115 bronze badges

answered Apr 24, 2017 at 7:57

Amit Gujarathi's user avatar

Amit GujarathiAmit Gujarathi

1,0601 gold badge12 silver badges25 bronze badges

There are three ways to do it depending on the application configuration file you are using

a) If you are using application.properties file set

server.port = 8090

b) If you are using application.yml file set server port property in YAML format as given below

server:
     port: 8090

c) You can also Set the property as the System property in the main method

System.setProperty("server.port","8090");

LukeSolar's user avatar

LukeSolar

3,7574 gold badges29 silver badges39 bronze badges

answered Oct 15, 2018 at 17:52

Praneeth's user avatar

PraneethPraneeth

5195 silver badges8 bronze badges

Add this in your application.properties file

server.port= 8080

Derick Daniel's user avatar

answered Jun 17, 2016 at 9:57

Sridhar Battala's user avatar

2

  1. As everyone said, you can specify in application.properties
    server.port = 9000 (could be any other value)

  2. If you are using spring actuator in your project, by default it points to
    8080, and if you want to change it, then in application.properties mention

    management.port = 9001 (could be any other value)

answered Sep 29, 2015 at 6:01

Rakesh's user avatar

RakeshRakesh

1,3341 gold badge14 silver badges22 bronze badges

In the application.properties file, add this line:

server.port = 65535

where to place that fie:

24.3 Application Property Files

SpringApplication loads properties from application.properties files
in the following locations and adds them to the Spring Environment:

A /config subdirectory of the current directory
The current directory
A classpath /config package
The classpath root

The list is ordered by precedence (properties defined in locations
higher in the list override those defined in lower locations).

In my case I put it in the directory where the jar file stands.

From:

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-application-property-files

answered Dec 20, 2018 at 1:28

ZhaoGang's user avatar

ZhaoGangZhaoGang

4,29324 silver badges36 bronze badges

By default spring boot app start with embedded tomcat server start at default port 8080. spring provides you with following different customization you can choose one of them.

NOTE – you can use server.port=0 spring boot will find any unassigned http random port
for us.

1) application.properties

server.port=2020

2) application.yml

server:  
     port : 2020

3) Change the server port programatically

3.1) By implementing WebServerFactoryCustomizer interface — Spring 2.x

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // customize the factory here
        factory.setPort(2020);
    }
}

3.2) By Implementing EmbeddedServletContainerCustomizer interface — Spring 1.x

@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        // customize here
        container.setPort(2020);
    }
}

4) By using command line option

 java -jar spring-boot-app.jar -Dserver.port=2020

answered Apr 26, 2019 at 14:09

anandchaugule's user avatar

Indeed, the easiest way is to set the server.port property.

If you are using STS as IDE, from version 3.6.7 you actually have Spring Properties Editor for opening the properties file.

This editor provides autocomplete for all Spring Boot properties. If you write port and hit CTRL + SPACE, server.port will be the first option.

answered Dec 15, 2015 at 9:11

Adrian Cosma's user avatar

1

By default, spring-web module provides an embedded tomcat server that is running under the port number 8080. If you need to change the port number of the application then go to application.properties file and configure the port number by using server.port property.

  server.port= 9876

then your application is running under the port 9876.

answered May 14, 2020 at 9:46

Nafaz M N M's user avatar

Nafaz M N MNafaz M N M

1,4232 gold badges17 silver badges36 bronze badges

Hope this one help

application.properties=> 

server.port=8090

application.yml=> 

server
  port:8090

answered May 18, 2018 at 13:14

Sagar Mal Shankhala's user avatar

1

Using property server.port=8080 for instance like mentioned in other answers is definitely a way to go. Just wanted to mention that you could also expose an environment property:

SERVER_PORT=8080

Since spring boot is able to replace «.» for «_» and lower to UPPER case for environment variables in recent versions.
This is specially useful in containers where all you gotta do is define that environment variable without adding/editing application.properties or passing system properties through command line (i.e -Dserver.port=$PORT)

Derick Daniel's user avatar

answered Jul 29, 2016 at 21:25

Ulises's user avatar

UlisesUlises

8,8452 gold badges29 silver badges27 bronze badges

1

You can add the port in below methods.

  1. Run -> Configurations section

  2. In application.xml add server.port=XXXX

Bogdan Bogdanov's user avatar

answered Feb 2, 2016 at 15:45

gkarthiks's user avatar

gkarthiksgkarthiks

4466 silver badges17 bronze badges

1

Just have a application.properties in src/main/resources of the project and give there

server.port=****

where **** refers to the port number.

gawi's user avatar

gawi

2,7934 gold badges32 silver badges44 bronze badges

answered Jul 2, 2017 at 7:07

Shubham Khurana's user avatar

1.1 Update via a properties file.

/src/main/resources/application.properties

server.port=8888

Update via a yaml file.

   server:

     port: 8888

EmbeddedServletContainerCustomizer

@Component
public class CustomContainer implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {

        container.setPort(8888);

    }

}

Jakub Matczak's user avatar

answered Aug 28, 2017 at 10:01

Buddhika Lakshan's user avatar

Providing the port number in application.properties file will resolve the issue

 server.port = 8080

«port depends on your choice, where you want to host the application»

answered Oct 15, 2018 at 12:52

Ashwini's user avatar

AshwiniAshwini

74110 silver badges5 bronze badges

You can set that in application.properties under /src/main/resources/

server.port = 8090

answered May 13, 2016 at 22:54

Abhijeet's user avatar

AbhijeetAbhijeet

5,4405 gold badges41 silver badges46 bronze badges

By Default Spring-web module provides an embedded tomcat server runs on port number 8080.

You can change it as follows —

A) If you are using gradle then use can set the property in your application.yml :

 server:  
      port: 8042

B) If you are using maven then you can set the property in your application.properties :

server.port: 8042

C) When you have port in your own config file and want to set it during runtime.

 By implementing WebServerFactoryCustomizer interface — Spring 2.x

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // customize the factory here
        factory.setPort(8042);
    }
}

 By Implementing EmbeddedServletContainerCustomizer interface — Spring 1.x

@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        // customize here
        container.setPort(8042);
    }
}

answered May 16, 2021 at 18:39

Ishan Garg's user avatar

Ishan GargIshan Garg

5414 silver badges12 bronze badges

1

How do I configure the TCP/IP port listened on by a Spring Boot application, so it does not use the default port of 8080.

Tung's user avatar

Tung

1,5194 gold badges15 silver badges32 bronze badges

asked Jan 13, 2014 at 2:59

Paul Verest's user avatar

Paul VerestPaul Verest

58.3k47 gold badges197 silver badges323 bronze badges

4

As said in docs either set server.port as system property using command line option to jvm -Dserver.port=8090 or add application.properties in /src/main/resources/ with

server.port=8090

For a random port use:

server.port=0

Similarly add application.yml in /src/main/resources/ with:

server:
  port: 8090

blacktide's user avatar

blacktide

9,9707 gold badges32 silver badges51 bronze badges

answered Jan 13, 2014 at 3:14

Paul Verest's user avatar

Paul VerestPaul Verest

58.3k47 gold badges197 silver badges323 bronze badges

16

There are two main ways to change the port in the Embedded Tomcat in a Spring Boot Application.

Modify application.properties

First you can try the application.properties file in the /resources folder:

server.port = 8090

application.properties file

Modify a VM option

The second way, if you want to avoid modifying any files and checking in something that you only need on your local, you can use a vm arg:

Go to Run -> Edit Configurations -> VM options

-Dserver.port=8090

Change port with a vm arg

Additionally, if you need more information you can view the following blog post here: Changing the port on a Spring Boot Application

answered May 14, 2015 at 23:57

anataliocs's user avatar

1

Since Spring Boot provides various configuration externalization mechanism (through various PropertySource implementations and/or processors wired into Environment object in order), you can set any property outside of your jar archive through following methods:

  1. Pass property through command line argument as application argument

    java -jar <path/to/my/jar> --server.port=7788
    
  2. From property in SPRING_APPLICATION_JSON (Spring Boot 1.3.0+)

    • Define environment variable in U*IX shell:

      SPRING_APPLICATION_JSON='{"server.port":7788}' java -jar <path/to/my/jar>
      
    • By using Java system property:

      java -Dspring.application.json='{"server.port":7788}' -jar <path/to/my/jar>
      
    • Pass through command line argument:

      java -jar <path/to/my/jar> --spring.application.json='{"server.port":7788}'
      
  3. Define JVM system property

    java -Dserver.port=7788 -jar <path/to/my/jar>
    
  4. Define OS environment variable

    • U*IX Shell

      SERVER_PORT=7788 java -jar <path/to/my/jar>
      
    • Windows

      SET SERVER_PORT=7788
      java -jar <path/to/my/jar>
      
  5. Place property in ./config/application.properties configuration file

    server.port=7788
    

    and run:

     java -jar <path/to/my/jar>
    
  6. Place property in ./config/application.yaml

    server:
        port: 7788
    

    and run:

     java -jar <path/to/my/jar>
    
  7. Place property in ./application.properties

    server.port=7788
    

    and run:

     java -jar <path/to/my/jar>
    
  8. Place property in ./application.yaml

    server:
        port: 7788
    

    and run:

     java -jar <path/to/my/jar>
    

You can combine above methods all together, and the former configuration in the list take precedence over the latter one.

For example:

SERVER_PORT=2266 java -Dserver.port=5566 -jar <path/to/my/jar> --server.port=7788

The server will start and listen on port 7788.

This is very useful providing default properties in PropertySources with lower precedence (and usually packaged in the archive or coded in the source), and then override it in the runtime environment. And it is the design philosophy of Spring Boot:

Be opinionated out of the box, but get out of the way quickly as requirements start to diverge from the defaults.


SERVER_NAME to server.name conversion was done by Relaxed Binding.

answered Nov 29, 2016 at 17:39

tan9's user avatar

tan9tan9

3,3302 gold badges17 silver badges21 bronze badges

0

Also, you can configure the port programmatically.

For Spring Boot 2.x.x:

@Configuration
public class CustomContainer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
  public void customize(ConfigurableServletWebServerFactory factory){
    factory.setPort(8042);
  }
}

For older versions:

@Configuration
public class ServletConfig {
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return (container -> {
            container.setPort(8012);
        });
    }
}

Positive Navid's user avatar

answered Nov 3, 2015 at 18:29

makerj's user avatar

makerjmakerj

2,0992 gold badges18 silver badges27 bronze badges

8

If you would like to run it locally, use this —

mvn spring-boot:run -Drun.jvmArguments='-Dserver.port=8085'

As of Spring Boot 2.0, here’s the command that works (clues were here):

mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8085

Brent Bradburn's user avatar

answered Apr 15, 2016 at 23:00

itwarilal's user avatar

itwarilalitwarilal

1,2249 silver badges16 bronze badges

1

You can set port in java code:

HashMap<String, Object> props = new HashMap<>();
props.put("server.port", 9999);

new SpringApplicationBuilder()
    .sources(SampleController.class)                
    .properties(props)
    .run(args);

Or in application.yml:

server:
    port: 9999

Or in application.properties:

server.port=9999

Or as a command line parameter:

-Dserver.port=9999

answered Mar 17, 2016 at 16:58

ayurchuk's user avatar

ayurchukayurchuk

1,8291 gold badge15 silver badges13 bronze badges

2

In case you are using application.yml add the Following lines to it

server:
     port: 9000

and of course 0 for random port.

Paul Verest's user avatar

Paul Verest

58.3k47 gold badges197 silver badges323 bronze badges

answered Dec 3, 2014 at 19:30

gatolgaj's user avatar

gatolgajgatolgaj

1,1717 silver badges12 bronze badges

2

As explained in Spring documentation, there are several ways to do that:

Either you set the port in the command line (for example 8888)

-Dserver.port=8888 or --server.port=8888

Example : java -jar -Dserver.port=8888 test.jar

Or you set the port in the application.properties

server.port=${port:4588}

or (in application.yml with yaml syntax)

server:
   port: ${port:4588}

If the port passed by -Dport (or -Dserver.port) is set in command line then this port will be taken into account. If not, then the port will be 4588 by default.

If you want to enforce the port in properties file whatever the environment variable, you just have to write:

server.port=8888

answered Jan 21, 2017 at 13:21

OlivierTerrien's user avatar

OlivierTerrienOlivierTerrien

2,3611 gold badge19 silver badges31 bronze badges

Include below property in application.properties

server.port=8080

Derick Daniel's user avatar

answered Oct 18, 2016 at 18:22

Chandramouli's user avatar

1

When you need a programatically way of doing it, you can set it during startup:

System.getProperties().put( "server.port", 80 );
SpringApplication.run(App.class, args);

This might help for things like environment dependent port.
Have a nice day

answered Apr 3, 2016 at 16:21

Luis Mauricio's user avatar

2

if you are using gradle as the build tool, you can set the server port in your application.yml file as:

server:
  port: 8291

If you are using maven then the port can be set in your application.properties file as:

server.port: 8291

Gaurav Jeswani's user avatar

answered Oct 24, 2019 at 9:20

VSharma's user avatar

VSharmaVSharma

4714 silver badges8 bronze badges

2

To extend other answers:

There is a section in the docs for testing which explains how to configure the port on integration tests:

  • 41.3 Testing Spring Boot applications
  • 41.3.3 Working with random ports

At integration tests, the port configuration is made using the annotation @SpringBootTest and the webEnvironment values.


Random port:

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)

You can inject the value using @LocalServerPort which is the same as @Value("${local.server.port}").

  • Example:

Random port test configuration:

@RunWith(SpringRunner.class
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ExampleTest {
   ...
   @LocalServerPort //to inject port value
   int port;
}

Defined port:

@SpringBootTest(webEnvironment=WebEnvironment.DEFINED_PORT)

It takes the value from server.port if is defined.

  • If is defined using @TestPropertySource(properties = "server.port=9192"), it overrides other defined values.
  • If not, it takes the value from src/test/resources/application.properties (if exists).
  • And finally, if it is not defined it starts with the default 8080.

Example:

Defined port test configuration:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties = "server.port=9192")
public class DemoApplicationTests {

    @Test
    public void contextLoads() {
    }

}

andi's user avatar

andi

9311 gold badge12 silver badges17 bronze badges

answered May 29, 2017 at 18:40

Pau's user avatar

PauPau

14.3k13 gold badges64 silver badges90 bronze badges

You can specify port by overriding EmbeddedServletContainerFactory bean within your configuration (java based or xml). There you can specify port for used embedded servlet container. Please, see Spring Boot — Core «Embedded Servlet Container Support» paragraph and example there. Hope this helps.

Will's user avatar

Will

6,4613 gold badges32 silver badges41 bronze badges

answered Jan 13, 2014 at 10:20

nndru's user avatar

nndrunndru

2,03721 silver badges15 bronze badges

2

In application.properties file present in resources:

server.port=8082

FelixSFD's user avatar

FelixSFD

5,94210 gold badges46 silver badges115 bronze badges

answered Apr 24, 2017 at 7:57

Amit Gujarathi's user avatar

Amit GujarathiAmit Gujarathi

1,0601 gold badge12 silver badges25 bronze badges

There are three ways to do it depending on the application configuration file you are using

a) If you are using application.properties file set

server.port = 8090

b) If you are using application.yml file set server port property in YAML format as given below

server:
     port: 8090

c) You can also Set the property as the System property in the main method

System.setProperty("server.port","8090");

LukeSolar's user avatar

LukeSolar

3,7574 gold badges29 silver badges39 bronze badges

answered Oct 15, 2018 at 17:52

Praneeth's user avatar

PraneethPraneeth

5195 silver badges8 bronze badges

Add this in your application.properties file

server.port= 8080

Derick Daniel's user avatar

answered Jun 17, 2016 at 9:57

Sridhar Battala's user avatar

2

  1. As everyone said, you can specify in application.properties
    server.port = 9000 (could be any other value)

  2. If you are using spring actuator in your project, by default it points to
    8080, and if you want to change it, then in application.properties mention

    management.port = 9001 (could be any other value)

answered Sep 29, 2015 at 6:01

Rakesh's user avatar

RakeshRakesh

1,3341 gold badge14 silver badges22 bronze badges

In the application.properties file, add this line:

server.port = 65535

where to place that fie:

24.3 Application Property Files

SpringApplication loads properties from application.properties files
in the following locations and adds them to the Spring Environment:

A /config subdirectory of the current directory
The current directory
A classpath /config package
The classpath root

The list is ordered by precedence (properties defined in locations
higher in the list override those defined in lower locations).

In my case I put it in the directory where the jar file stands.

From:

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-application-property-files

answered Dec 20, 2018 at 1:28

ZhaoGang's user avatar

ZhaoGangZhaoGang

4,29324 silver badges36 bronze badges

By default spring boot app start with embedded tomcat server start at default port 8080. spring provides you with following different customization you can choose one of them.

NOTE – you can use server.port=0 spring boot will find any unassigned http random port
for us.

1) application.properties

server.port=2020

2) application.yml

server:  
     port : 2020

3) Change the server port programatically

3.1) By implementing WebServerFactoryCustomizer interface — Spring 2.x

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // customize the factory here
        factory.setPort(2020);
    }
}

3.2) By Implementing EmbeddedServletContainerCustomizer interface — Spring 1.x

@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        // customize here
        container.setPort(2020);
    }
}

4) By using command line option

 java -jar spring-boot-app.jar -Dserver.port=2020

answered Apr 26, 2019 at 14:09

anandchaugule's user avatar

Indeed, the easiest way is to set the server.port property.

If you are using STS as IDE, from version 3.6.7 you actually have Spring Properties Editor for opening the properties file.

This editor provides autocomplete for all Spring Boot properties. If you write port and hit CTRL + SPACE, server.port will be the first option.

answered Dec 15, 2015 at 9:11

Adrian Cosma's user avatar

1

By default, spring-web module provides an embedded tomcat server that is running under the port number 8080. If you need to change the port number of the application then go to application.properties file and configure the port number by using server.port property.

  server.port= 9876

then your application is running under the port 9876.

answered May 14, 2020 at 9:46

Nafaz M N M's user avatar

Nafaz M N MNafaz M N M

1,4232 gold badges17 silver badges36 bronze badges

Hope this one help

application.properties=> 

server.port=8090

application.yml=> 

server
  port:8090

answered May 18, 2018 at 13:14

Sagar Mal Shankhala's user avatar

1

Using property server.port=8080 for instance like mentioned in other answers is definitely a way to go. Just wanted to mention that you could also expose an environment property:

SERVER_PORT=8080

Since spring boot is able to replace «.» for «_» and lower to UPPER case for environment variables in recent versions.
This is specially useful in containers where all you gotta do is define that environment variable without adding/editing application.properties or passing system properties through command line (i.e -Dserver.port=$PORT)

Derick Daniel's user avatar

answered Jul 29, 2016 at 21:25

Ulises's user avatar

UlisesUlises

8,8452 gold badges29 silver badges27 bronze badges

1

You can add the port in below methods.

  1. Run -> Configurations section

  2. In application.xml add server.port=XXXX

Bogdan Bogdanov's user avatar

answered Feb 2, 2016 at 15:45

gkarthiks's user avatar

gkarthiksgkarthiks

4466 silver badges17 bronze badges

1

Just have a application.properties in src/main/resources of the project and give there

server.port=****

where **** refers to the port number.

gawi's user avatar

gawi

2,7934 gold badges32 silver badges44 bronze badges

answered Jul 2, 2017 at 7:07

Shubham Khurana's user avatar

1.1 Update via a properties file.

/src/main/resources/application.properties

server.port=8888

Update via a yaml file.

   server:

     port: 8888

EmbeddedServletContainerCustomizer

@Component
public class CustomContainer implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {

        container.setPort(8888);

    }

}

Jakub Matczak's user avatar

answered Aug 28, 2017 at 10:01

Buddhika Lakshan's user avatar

Providing the port number in application.properties file will resolve the issue

 server.port = 8080

«port depends on your choice, where you want to host the application»

answered Oct 15, 2018 at 12:52

Ashwini's user avatar

AshwiniAshwini

74110 silver badges5 bronze badges

You can set that in application.properties under /src/main/resources/

server.port = 8090

answered May 13, 2016 at 22:54

Abhijeet's user avatar

AbhijeetAbhijeet

5,4405 gold badges41 silver badges46 bronze badges

By Default Spring-web module provides an embedded tomcat server runs on port number 8080.

You can change it as follows —

A) If you are using gradle then use can set the property in your application.yml :

 server:  
      port: 8042

B) If you are using maven then you can set the property in your application.properties :

server.port: 8042

C) When you have port in your own config file and want to set it during runtime.

 By implementing WebServerFactoryCustomizer interface — Spring 2.x

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // customize the factory here
        factory.setPort(8042);
    }
}

 By Implementing EmbeddedServletContainerCustomizer interface — Spring 1.x

@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        // customize here
        container.setPort(8042);
    }
}

answered May 16, 2021 at 18:39

Ishan Garg's user avatar

Ishan GargIshan Garg

5414 silver badges12 bronze badges

1

How do I configure the TCP/IP port listened on by a Spring Boot application, so it does not use the default port of 8080.

Tung's user avatar

Tung

1,5194 gold badges15 silver badges32 bronze badges

asked Jan 13, 2014 at 2:59

Paul Verest's user avatar

Paul VerestPaul Verest

58.3k47 gold badges197 silver badges323 bronze badges

4

As said in docs either set server.port as system property using command line option to jvm -Dserver.port=8090 or add application.properties in /src/main/resources/ with

server.port=8090

For a random port use:

server.port=0

Similarly add application.yml in /src/main/resources/ with:

server:
  port: 8090

blacktide's user avatar

blacktide

9,9707 gold badges32 silver badges51 bronze badges

answered Jan 13, 2014 at 3:14

Paul Verest's user avatar

Paul VerestPaul Verest

58.3k47 gold badges197 silver badges323 bronze badges

16

There are two main ways to change the port in the Embedded Tomcat in a Spring Boot Application.

Modify application.properties

First you can try the application.properties file in the /resources folder:

server.port = 8090

application.properties file

Modify a VM option

The second way, if you want to avoid modifying any files and checking in something that you only need on your local, you can use a vm arg:

Go to Run -> Edit Configurations -> VM options

-Dserver.port=8090

Change port with a vm arg

Additionally, if you need more information you can view the following blog post here: Changing the port on a Spring Boot Application

answered May 14, 2015 at 23:57

anataliocs's user avatar

1

Since Spring Boot provides various configuration externalization mechanism (through various PropertySource implementations and/or processors wired into Environment object in order), you can set any property outside of your jar archive through following methods:

  1. Pass property through command line argument as application argument

    java -jar <path/to/my/jar> --server.port=7788
    
  2. From property in SPRING_APPLICATION_JSON (Spring Boot 1.3.0+)

    • Define environment variable in U*IX shell:

      SPRING_APPLICATION_JSON='{"server.port":7788}' java -jar <path/to/my/jar>
      
    • By using Java system property:

      java -Dspring.application.json='{"server.port":7788}' -jar <path/to/my/jar>
      
    • Pass through command line argument:

      java -jar <path/to/my/jar> --spring.application.json='{"server.port":7788}'
      
  3. Define JVM system property

    java -Dserver.port=7788 -jar <path/to/my/jar>
    
  4. Define OS environment variable

    • U*IX Shell

      SERVER_PORT=7788 java -jar <path/to/my/jar>
      
    • Windows

      SET SERVER_PORT=7788
      java -jar <path/to/my/jar>
      
  5. Place property in ./config/application.properties configuration file

    server.port=7788
    

    and run:

     java -jar <path/to/my/jar>
    
  6. Place property in ./config/application.yaml

    server:
        port: 7788
    

    and run:

     java -jar <path/to/my/jar>
    
  7. Place property in ./application.properties

    server.port=7788
    

    and run:

     java -jar <path/to/my/jar>
    
  8. Place property in ./application.yaml

    server:
        port: 7788
    

    and run:

     java -jar <path/to/my/jar>
    

You can combine above methods all together, and the former configuration in the list take precedence over the latter one.

For example:

SERVER_PORT=2266 java -Dserver.port=5566 -jar <path/to/my/jar> --server.port=7788

The server will start and listen on port 7788.

This is very useful providing default properties in PropertySources with lower precedence (and usually packaged in the archive or coded in the source), and then override it in the runtime environment. And it is the design philosophy of Spring Boot:

Be opinionated out of the box, but get out of the way quickly as requirements start to diverge from the defaults.


SERVER_NAME to server.name conversion was done by Relaxed Binding.

answered Nov 29, 2016 at 17:39

tan9's user avatar

tan9tan9

3,3302 gold badges17 silver badges21 bronze badges

0

Also, you can configure the port programmatically.

For Spring Boot 2.x.x:

@Configuration
public class CustomContainer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
  public void customize(ConfigurableServletWebServerFactory factory){
    factory.setPort(8042);
  }
}

For older versions:

@Configuration
public class ServletConfig {
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return (container -> {
            container.setPort(8012);
        });
    }
}

Positive Navid's user avatar

answered Nov 3, 2015 at 18:29

makerj's user avatar

makerjmakerj

2,0992 gold badges18 silver badges27 bronze badges

8

If you would like to run it locally, use this —

mvn spring-boot:run -Drun.jvmArguments='-Dserver.port=8085'

As of Spring Boot 2.0, here’s the command that works (clues were here):

mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8085

Brent Bradburn's user avatar

answered Apr 15, 2016 at 23:00

itwarilal's user avatar

itwarilalitwarilal

1,2249 silver badges16 bronze badges

1

You can set port in java code:

HashMap<String, Object> props = new HashMap<>();
props.put("server.port", 9999);

new SpringApplicationBuilder()
    .sources(SampleController.class)                
    .properties(props)
    .run(args);

Or in application.yml:

server:
    port: 9999

Or in application.properties:

server.port=9999

Or as a command line parameter:

-Dserver.port=9999

answered Mar 17, 2016 at 16:58

ayurchuk's user avatar

ayurchukayurchuk

1,8291 gold badge15 silver badges13 bronze badges

2

In case you are using application.yml add the Following lines to it

server:
     port: 9000

and of course 0 for random port.

Paul Verest's user avatar

Paul Verest

58.3k47 gold badges197 silver badges323 bronze badges

answered Dec 3, 2014 at 19:30

gatolgaj's user avatar

gatolgajgatolgaj

1,1717 silver badges12 bronze badges

2

As explained in Spring documentation, there are several ways to do that:

Either you set the port in the command line (for example 8888)

-Dserver.port=8888 or --server.port=8888

Example : java -jar -Dserver.port=8888 test.jar

Or you set the port in the application.properties

server.port=${port:4588}

or (in application.yml with yaml syntax)

server:
   port: ${port:4588}

If the port passed by -Dport (or -Dserver.port) is set in command line then this port will be taken into account. If not, then the port will be 4588 by default.

If you want to enforce the port in properties file whatever the environment variable, you just have to write:

server.port=8888

answered Jan 21, 2017 at 13:21

OlivierTerrien's user avatar

OlivierTerrienOlivierTerrien

2,3611 gold badge19 silver badges31 bronze badges

Include below property in application.properties

server.port=8080

Derick Daniel's user avatar

answered Oct 18, 2016 at 18:22

Chandramouli's user avatar

1

When you need a programatically way of doing it, you can set it during startup:

System.getProperties().put( "server.port", 80 );
SpringApplication.run(App.class, args);

This might help for things like environment dependent port.
Have a nice day

answered Apr 3, 2016 at 16:21

Luis Mauricio's user avatar

2

if you are using gradle as the build tool, you can set the server port in your application.yml file as:

server:
  port: 8291

If you are using maven then the port can be set in your application.properties file as:

server.port: 8291

Gaurav Jeswani's user avatar

answered Oct 24, 2019 at 9:20

VSharma's user avatar

VSharmaVSharma

4714 silver badges8 bronze badges

2

To extend other answers:

There is a section in the docs for testing which explains how to configure the port on integration tests:

  • 41.3 Testing Spring Boot applications
  • 41.3.3 Working with random ports

At integration tests, the port configuration is made using the annotation @SpringBootTest and the webEnvironment values.


Random port:

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)

You can inject the value using @LocalServerPort which is the same as @Value("${local.server.port}").

  • Example:

Random port test configuration:

@RunWith(SpringRunner.class
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ExampleTest {
   ...
   @LocalServerPort //to inject port value
   int port;
}

Defined port:

@SpringBootTest(webEnvironment=WebEnvironment.DEFINED_PORT)

It takes the value from server.port if is defined.

  • If is defined using @TestPropertySource(properties = "server.port=9192"), it overrides other defined values.
  • If not, it takes the value from src/test/resources/application.properties (if exists).
  • And finally, if it is not defined it starts with the default 8080.

Example:

Defined port test configuration:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties = "server.port=9192")
public class DemoApplicationTests {

    @Test
    public void contextLoads() {
    }

}

andi's user avatar

andi

9311 gold badge12 silver badges17 bronze badges

answered May 29, 2017 at 18:40

Pau's user avatar

PauPau

14.3k13 gold badges64 silver badges90 bronze badges

You can specify port by overriding EmbeddedServletContainerFactory bean within your configuration (java based or xml). There you can specify port for used embedded servlet container. Please, see Spring Boot — Core «Embedded Servlet Container Support» paragraph and example there. Hope this helps.

Will's user avatar

Will

6,4613 gold badges32 silver badges41 bronze badges

answered Jan 13, 2014 at 10:20

nndru's user avatar

nndrunndru

2,03721 silver badges15 bronze badges

2

In application.properties file present in resources:

server.port=8082

FelixSFD's user avatar

FelixSFD

5,94210 gold badges46 silver badges115 bronze badges

answered Apr 24, 2017 at 7:57

Amit Gujarathi's user avatar

Amit GujarathiAmit Gujarathi

1,0601 gold badge12 silver badges25 bronze badges

There are three ways to do it depending on the application configuration file you are using

a) If you are using application.properties file set

server.port = 8090

b) If you are using application.yml file set server port property in YAML format as given below

server:
     port: 8090

c) You can also Set the property as the System property in the main method

System.setProperty("server.port","8090");

LukeSolar's user avatar

LukeSolar

3,7574 gold badges29 silver badges39 bronze badges

answered Oct 15, 2018 at 17:52

Praneeth's user avatar

PraneethPraneeth

5195 silver badges8 bronze badges

Add this in your application.properties file

server.port= 8080

Derick Daniel's user avatar

answered Jun 17, 2016 at 9:57

Sridhar Battala's user avatar

2

  1. As everyone said, you can specify in application.properties
    server.port = 9000 (could be any other value)

  2. If you are using spring actuator in your project, by default it points to
    8080, and if you want to change it, then in application.properties mention

    management.port = 9001 (could be any other value)

answered Sep 29, 2015 at 6:01

Rakesh's user avatar

RakeshRakesh

1,3341 gold badge14 silver badges22 bronze badges

In the application.properties file, add this line:

server.port = 65535

where to place that fie:

24.3 Application Property Files

SpringApplication loads properties from application.properties files
in the following locations and adds them to the Spring Environment:

A /config subdirectory of the current directory
The current directory
A classpath /config package
The classpath root

The list is ordered by precedence (properties defined in locations
higher in the list override those defined in lower locations).

In my case I put it in the directory where the jar file stands.

From:

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-application-property-files

answered Dec 20, 2018 at 1:28

ZhaoGang's user avatar

ZhaoGangZhaoGang

4,29324 silver badges36 bronze badges

By default spring boot app start with embedded tomcat server start at default port 8080. spring provides you with following different customization you can choose one of them.

NOTE – you can use server.port=0 spring boot will find any unassigned http random port
for us.

1) application.properties

server.port=2020

2) application.yml

server:  
     port : 2020

3) Change the server port programatically

3.1) By implementing WebServerFactoryCustomizer interface — Spring 2.x

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // customize the factory here
        factory.setPort(2020);
    }
}

3.2) By Implementing EmbeddedServletContainerCustomizer interface — Spring 1.x

@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        // customize here
        container.setPort(2020);
    }
}

4) By using command line option

 java -jar spring-boot-app.jar -Dserver.port=2020

answered Apr 26, 2019 at 14:09

anandchaugule's user avatar

Indeed, the easiest way is to set the server.port property.

If you are using STS as IDE, from version 3.6.7 you actually have Spring Properties Editor for opening the properties file.

This editor provides autocomplete for all Spring Boot properties. If you write port and hit CTRL + SPACE, server.port will be the first option.

answered Dec 15, 2015 at 9:11

Adrian Cosma's user avatar

1

By default, spring-web module provides an embedded tomcat server that is running under the port number 8080. If you need to change the port number of the application then go to application.properties file and configure the port number by using server.port property.

  server.port= 9876

then your application is running under the port 9876.

answered May 14, 2020 at 9:46

Nafaz M N M's user avatar

Nafaz M N MNafaz M N M

1,4232 gold badges17 silver badges36 bronze badges

Hope this one help

application.properties=> 

server.port=8090

application.yml=> 

server
  port:8090

answered May 18, 2018 at 13:14

Sagar Mal Shankhala's user avatar

1

Using property server.port=8080 for instance like mentioned in other answers is definitely a way to go. Just wanted to mention that you could also expose an environment property:

SERVER_PORT=8080

Since spring boot is able to replace «.» for «_» and lower to UPPER case for environment variables in recent versions.
This is specially useful in containers where all you gotta do is define that environment variable without adding/editing application.properties or passing system properties through command line (i.e -Dserver.port=$PORT)

Derick Daniel's user avatar

answered Jul 29, 2016 at 21:25

Ulises's user avatar

UlisesUlises

8,8452 gold badges29 silver badges27 bronze badges

1

You can add the port in below methods.

  1. Run -> Configurations section

  2. In application.xml add server.port=XXXX

Bogdan Bogdanov's user avatar

answered Feb 2, 2016 at 15:45

gkarthiks's user avatar

gkarthiksgkarthiks

4466 silver badges17 bronze badges

1

Just have a application.properties in src/main/resources of the project and give there

server.port=****

where **** refers to the port number.

gawi's user avatar

gawi

2,7934 gold badges32 silver badges44 bronze badges

answered Jul 2, 2017 at 7:07

Shubham Khurana's user avatar

1.1 Update via a properties file.

/src/main/resources/application.properties

server.port=8888

Update via a yaml file.

   server:

     port: 8888

EmbeddedServletContainerCustomizer

@Component
public class CustomContainer implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {

        container.setPort(8888);

    }

}

Jakub Matczak's user avatar

answered Aug 28, 2017 at 10:01

Buddhika Lakshan's user avatar

Providing the port number in application.properties file will resolve the issue

 server.port = 8080

«port depends on your choice, where you want to host the application»

answered Oct 15, 2018 at 12:52

Ashwini's user avatar

AshwiniAshwini

74110 silver badges5 bronze badges

You can set that in application.properties under /src/main/resources/

server.port = 8090

answered May 13, 2016 at 22:54

Abhijeet's user avatar

AbhijeetAbhijeet

5,4405 gold badges41 silver badges46 bronze badges

By Default Spring-web module provides an embedded tomcat server runs on port number 8080.

You can change it as follows —

A) If you are using gradle then use can set the property in your application.yml :

 server:  
      port: 8042

B) If you are using maven then you can set the property in your application.properties :

server.port: 8042

C) When you have port in your own config file and want to set it during runtime.

 By implementing WebServerFactoryCustomizer interface — Spring 2.x

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // customize the factory here
        factory.setPort(8042);
    }
}

 By Implementing EmbeddedServletContainerCustomizer interface — Spring 1.x

@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        // customize here
        container.setPort(8042);
    }
}

answered May 16, 2021 at 18:39

Ishan Garg's user avatar

Ishan GargIshan Garg

5414 silver badges12 bronze badges

1

Spring boot server port can be changed in a number of ways, by overriding in properties file, JVM argument, command line arguments, build script or programmatically. Spring boot applications generally include embedded servers like Tomcat or Jetty, the default server port for these embedded servers is 8080. Spring boot provides a number of hooks via which you can easily override this default server port. We have tried a number of ways for overriding server ports and listing here all the solutions which work well and answer the question that in spring boot how to change server port.

Spring boot server port is changed in application.properties or YML file easily. Server port is overridden using command line arguments, JVM arguments, spring application json or programmatically within the code. Spring boot application running via using commands like jar, gradle, maven or spring boot then all provides an option to override the spring boot embedded server port.

This article will provide a bonus factor. With each example, you will learn a new way to run spring boot applications. If you want to learn the different ways to run a spring boot application, then following examples will serve the purpose. So we can say the different ways to run spring boot application or the different ways to change spring boot server port are following:

1. Change spring boot server port in application.properties file

The spring boot application’s default server port can be overridden in application.properties. The property key name is server.port and which can be mentioned anywhere in application.properties file. For example, if we have to override default server port with value 8081 then in application.properties file, we will add following line

server.port=8081

Application.properties file use default value if no value provided

In application.properties file, you can mention the default value if a custom value is not supplied. In absence of custom value, the default value, mentioned earlier will be used.

server.port=${port:8081}

In this example, ‘port’ argument can be supplied as a JVM argument or environment variable. If ‘port’ value is present while starting application then it will override the default server port value. If ‘port’ value is absent then default value 8081, mentioned in application.properites file will be used.

2. Change spring boot server port in application.yml file

Application.yml properties provide similar functionality to override server port. Due to yml syntax, the syntax to mention server.port key differs but the functionality remains the same.

server
  port=8082

3. Change spring boot server port programmatically

Spring boot server port can be overriden programmatically too. Two options are available here. In the First option, you can pass it as default properties in the main method, which will get executed before starting the server. Another option is to implement the WebServerFactoryCustomizer interface and get a callback with the server factory to update configuration.

Following is the example, if you want to override the server port from the main method itself.

@SpringBootApplication
public class SandApplication {
  public static void main(String[] args) {
     SpringApplication app = new SpringApplication(SandApplication.class);
     app.setDefaultProperties(
           Collections.singletonMap("server.port", "8083"));
     app.run(args);
  }
}

Alternatively you can use WebServerFactoryCustomizer interface. The  WebServerFactoryCustomizer is a Strategy interface for customizing the web server provided factories. A bean of WebServerFactoryCustomizer type will get a callback with the server factory before the server is started, here you can set the address, port, error pages etc.

@Component
public class CustomPort implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
  @Override
  public void customize(ConfigurableServletWebServerFactory server) {
     server.setPort(8084);
  }
}

4. Change spring boot server port via Passing command line argument 

Command line arguments can be passed in Spring boot application as application arguments. While running the jar using command ‘Java -Jar’ you can add the command line ‘-server.port’ argument at the end and provide the port number on which you want to run the application.

Syntax

java -jar <path/to/my/jar> --server.port=PORT_NUMBER

Example

java -jar demo1-0.0.1-SNAPSHOT.jar --server.port=8085

5. Change spring boot server port via JVM arguments

JVM arguments can be used to define the spring boot server port. While running Java commands, you can pass the server.port argument as a normal JVM argument, which will be used internally by Spring boot to override default server port. In this example, we are running spring boot jar with Java command and passing server.port argument as JVM argument.

Syntax

java -Dserver.port=PORT_NUMBER -jar <path/to/my/jar>

Example

java -Dserver.port=8086 -jar demo.0.1-SNAPSHOT.jar

6. Spring boot change server port within intellij 

Whatever IDE you are using, almost every IDE has an option to set JVm arguments. From IDE’s graphical interface it becomes easy to add JVM arguments. Some IDEs have this option as VM arguments or VM options. 

Following is the example screenshot for setting spring boot server boot as VM options in IntelliJ Idea IDE.

intellij idea set server port as VM options

Intellij idea set server port as VM options

7. Change spring boot server port via SPRING_APPLICATION_JSON

The SPRING_APPLICATION_JSON property is used by Spring boot application to use properties to specify as inline embedded JSON to be used in system property or environment variables. From the Unix shell command line, you can supply the SPRING_APPLICATION_JSON properties while running Java command. In the following example, we are passing server.port as json with a value of 8088 as server port.

Example

 SPRING_APPLICATION_JSON='{"server.port":8088}' java -jar sand-0.0.1-SNAPSHOT.jar

8. Change spring boot server port via spring.application.json as JVM argument

The spring.application.json property is treated as alternative to SPRING_APPLICATION_JSON, So its behavior is completely same, The spring.application.json property can be passed as JVM argument and can have a JSON value including any number of properties as well as nested type of objects as json. In following example we are passing server.port key with value 8089 as json to override spring boot default server port

Example

java -Dspring.application.json='{"server.port":8089}' -jar sand-0.0.1-SNAPSHOT.jar 

9. Change spring boot server port via spring.application.json as command line argument

The spring.application.json property with json value can be treated as a normal command argument and can be supplied to Java command while running spring boot application via command line. In the following example, we are passing server.port with value 8090 to override default server port in spring boot application.

Example:

java -jar sand-0.0.1-SNAPSHOT.jar --spring.application.json='{"server.port":8090}' 

10. Change spring boot server port via Spring Boot Gradle Plugin

In build.gradle, file you can also specify the server port to be used in spring boot’s embedded server. You can arguments, which will be automatically supplied to application when application is run using Spring boot’s bootRun command For this either you should be using Spring boot Gralde plugin or Spring dependency management

In build.gradle file add following snippet:

bootRun {
  args += ["--server.port=8091"]
}

After adding the above snippet, you should start your application using the bootRun command. Those who have not used it earlier, this is a task present in the gradle file automatically when you create a Spring boot project from Spring boot initializer.

In Gradle tasks you can find at the location, applicationName > tasks > application > bootRun. Double click on bootRun and you will see your spring boot application starts with the server port as mentioned by you in build.gradle.

11. Change spring boot server port for test cases

The annotation @SpringBootTest is provided by spring boot which is an alternative to spring-test @ContextConfiguration annotation. It’s very often, you want to run test cases or integration tests on different ports, as on the original port the application may already be running. 

By default, the server will not be started by @SpringBootTest annotation. The webEnvironment attribute of @SpringBootTest annotation is used to specify how to run the test cases. It can have multiple values, but we will stick to our focus only to set server port value and keeping other things out of discussion. 

Note:Before proceeding further, you should check the version of JUnit, you are using. If you are creating test cases using JUnit 4, then you must have @RunWith(SpringRunner.class) annotation at test class level, otherwise the annotations will be ignored. For JUnit 5, you don’t need to do anything, as @SpringBootTest already internally does this work.

The webEnvironment has following cases to change server port.

1. RANDOM_PORT: With this option, a random number is used as a server port. The WebServerApplicationContext provides a real web environment, where embedded servers are started and a random port number is set as server port.

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class DemoTest {
  ….// test cases
}

2. DEFINED_PORT: Here the server port’s overridden value is used and in absence of any configuration, the default port 8080 is used. The WebServerApplicationContext gets loaded and provides a real web environment, the embedded servers are started with either defined server port or default server port.

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties = "server.port=8092")
public class DemoTest {
  ….// test cases
}

12. Change spring boot server port via gradle command line arguments

Spring boot application can be run from gradle command and while running application using gradle command, we pass arguments to override the system properties. In our case, we want to pass the server port value to be used by the embedded server in the spring boot application.

./gradlew bootRun --args='--server.port=8093'

In addition to overriding system properties, we can also process custom arguments via gradle command line arguments. To process a custom argument, let’s add the following snippet to your build.gradle.

bootRun {
  if (project.hasProperty('args')) {
     args project.args.split(',')
  }
}

Once you have added above code then you can pass the custom arguments as ‘-P’, since we have used the name  ‘args’ in build.gradle then the following command can be used to pass the customer arguments.

 ./gradlew bootRun -Pargs=--server.port=8094

13. Change spring boot server port via maven command line arguments

Maven based spring boot can be started using spring-boot:run command. Along with this command you can pass runtime arguments. In our example, we can pass server port in following way:

mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8095

Conclusion

We hope this article will help you somehow. We have tried to include every possible configuration or method to demonstrate the different ways in spring boot how to change server port.

Как изменить порт по умолчанию в Spring Boot

1. Вступление

Spring Boot предоставляет разумные значения по умолчанию для многих свойств конфигурации. Тем не менее, нам иногда нужно настроить их с нашими значениями для конкретного случая.

Типичный вариант использования —changing the default port for the embedded server.

В этом кратком руководстве мы рассмотрим несколько способов добиться этого.

Дальнейшее чтение:

2. Использование файлов свойств

Самый быстрый и простой способ настроить Spring Boot — переопределить значения свойств по умолчанию.

Для порта сервера свойство, которое мы хотим изменить, —server.port.

По умолчанию встроенный сервер запускается на порту 8080. Let’s see how we can provide a different value in an application.properties file:

Теперь сервер запустится через порт 8081.

Точно так же мы можем сделать то же самое, если используем файлapplication.yml:

Оба файла загружаются автоматически Spring Boot, если они помещены в каталогsrc/main/resources приложения Maven.

2.1. Экологические порты

Если у нас есть приложение, развернутое в разных средах, мы можем захотеть, чтобы оно запускалось на разных портах в каждой системе.

Этого легко достичь, комбинируя подход к файлам свойств с профилями Spring. Specifically, we can create a property file for each environment.с

Например, у нас будет файлapplication-dev.properties с содержанием:

Затем мы добавим еще один файлapplication-qa.properties с другим портом:

Конфигурация файлов свойств должна быть достаточной для большинства случаев.

Однако есть и другие варианты для этой цели, так что давайте изучим и их.

3. Программная конфигурация

Мы можем настроить порт программным способом, задав конкретное свойство при запуске приложения или настроив конфигурацию встроенного сервера.

Во-первых, давайте посмотрим, как установить свойство в основном классе@SpringBootApplication:

@SpringBootApplication
public class CustomApplication {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(CustomApplication.class);
        app.setDefaultProperties(Collections
          .singletonMap("server.port", "8083"));
        app.run(args);
    }
}

Затем, чтобы настроить конфигурацию сервера, мы должны реализовать интерфейсWebServerFactoryCustomizer:

@Component
public class ServerPortCustomizer
  implements WebServerFactoryCustomizer {

    @Override
    public void customize(ConfigurableWebServerFactory factory) {
        factory.setPort(8086);
    }
}

Обратите внимание, что это относится к версии Spring Boot 2.x.

Для Spring Boot 1.x мы можем аналогичным образом реализовать интерфейсEmbeddedServletContainerCustomizer.

4. Использование аргументов командной строки

При упаковке и запуске нашего приложения как jar-файла мы можем установить аргументserver.port с помощью командыjava:

java -jar spring-5.jar --server.port=8083

Или используя эквивалентный синтаксис:

java -jar -Dserver.port=8083 spring-5.jar

5. Порядок оценки

В заключение давайте посмотрим на порядок, в котором эти подходы оцениваются Spring Boot.

В основном, приоритет конфигурации:

  • конфигурация встроенного сервера

  • аргументы командной строки

  • файлы свойств

  • основная конфигурация@SpringBootApplication

6. Заключение

В этом кратком руководстве мы увидели, как настроить порт сервера в приложении Spring Boot.

March 20, 2017

This page will walk through how to change spring boot default server port. When spring boot application starts, the embedded server such as Tomcat starts with a default port. The embedded tomcat starts with 8080 port as default. There are many ways to change default server port. We can use property file, system variables and arguments with java command to change embedded servlet container settings such as default server port. We can also change embedded servlet container settings programmatically. In property file we configure server.port property with server port value and we configure SERVER_PORT as system variable. Now find the example.

Contents
  • Using Property File (.properties/.yml)
  • Using java Command with —server.port or -Dserver.port
  • Using java Command with —port or -Dport in Short
  • Using SERVER_PORT as OS Environment Variable
  • Using SERVER.PORT with SpringApplication Programmatically
  • Using EmbeddedServletContainerCustomizer
  • Using Eclipse Run Configurations with Environment Variable
  • Using Eclipse Run Configurations with Arguments
  • References

Using Property File (.properties/.yml)

To change server port using property file, we need to configure server.port property.

a. Using application.properties in classpath such as
srcmainresourcesapplication.properties

Server will start with 8585 port. To get random server port, assign 0 to the property.

Now spring boot will start server on a port that is not being used currently by any server in the system.

b. Using application.yml in classpath such as srcmainresourcesapplication.yml.

Server will start with 8585 port. For random port, assign 0.

Using java Command with —server.port or -Dserver.port

Suppose we have an executable JAR named as my-app.jar, then while starting spring boot application using java command we can use argument as following.

Using —server.port

java -jar my-app.jar  --server.port=8585 

Using -Dserver.port

java -jar -Dserver.port=8585 my-app.jar 

Server will start with 8585 port.

Using java Command with —port or -Dport in Short

To make —server.port and -Dserver.port in short, we can remove server keyword and make it any short keyword such as —port and -Dport. We can use any short keyword. Here we are using port as short keyword. To achieve it we need to configure placeholder in property file as follows.

Using application.properties

Using application.yml

server:
  port: ${port:8282} 

If we do not pass port as argument then by default server will start with 8282. If we want different port, then we need to pass desired port in argument as follows. Suppose we have an executable JAR named as my-app.jar.

Using —port

java -jar my-app.jar --port=8585 

Using -Dport

java -jar -Dport=8585 my-app.jar 

Server will start with 8585 port.

Using SERVER_PORT as OS Environment Variable

We can change the spring boot default server port by setting SERVER_PORT as OS (such as Windows and Linux) environment variable. In my example I have Windows 7. Find the steps to configure environment variable.

Step 1: Right click on Computer icon then go to Properties -> Advanced System Settings -> Environment Variables and set variable as follows.

Step 2: Open the command prompt and build the project. Suppose we get an executable JAR as my-app.jar then run it using java command as follows.

Server will start with 8585 port.

If we want to run spring boot application from eclipse console, first restart the eclipse and then run the application.

Using SERVER.PORT with SpringApplication Programmatically

SpringApplication has a method as setDefaultProperties() that is used to change spring boot default properties. Suppose we want to change default port then we need to create a Map and put a port with SERVER.PORT key. Find the example.

MyApplication.java

package com.concretepage;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
	public static void main(String[] args) {
		SpringApplication application = new SpringApplication(MyApplication.class);
		Map<String, Object> map = new HashMap<>();
		map.put("SERVER.PORT", "8585");
		application.setDefaultProperties(map);
		application.run(args);
        }     
} 

Spring boot will start the server with 8585 port.

Using EmbeddedServletContainerCustomizer

We can change embedded servlet container default settings registering a bean that implements EmbeddedServletContainerCustomizer interface. We need to override its customize() method. Find the example.

ContainerCustomizerBean.java

package com.concretepage.bean;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.stereotype.Component;
@Component
public class ContainerCustomizerBean implements EmbeddedServletContainerCustomizer {
	@Override
	public void customize(ConfigurableEmbeddedServletContainer container) {
		container.setPort(8585);
	}
} 

Spring boot will start server with 8585 port.

Using Eclipse Run Configurations with Environment Variable

We can change spring boot default settings in eclipse by configuring Environment variable in run configurations.

Step-1: Right click on the class and go to Run As -> Run Configurations

Step-2: Click on the Environment tab and server port as follows.

Find the print screen of eclipse.

Spring Boot Change Default Server Port

Step-3: Run the application from eclipse console. Server will start with 8585 port.

Using Eclipse Run Configurations with Arguments

To run spring boot application in eclipse, we run the class containing main() method with SpringApplication as java application. To change the default port, follow the steps.

Step-1: Right click on the class and go to Run As -> Run Configurations

Step-2: Click on the Arguments tab and configure server port as follows.

Find the print screen of eclipse.

Spring Boot Change Default Server Port

Step-3: Run the application from eclipse console. Server will start with 8585 port. Find the console output.

 .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _    
( ( )___ | '_ | '_| | '_ / _` |    
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |___, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.2.RELEASE)

2017-03-20 20:08:15.851  INFO 3888 --- [           main] com.concretepage.MyApplication           : Starting MyApplication on Renu-PC with PID 3888 (F:arvindPROJECTmarsspring-bootspring-boot-demotargetclasses started by Renu in F:arvindPROJECTmarsspring-bootspring-boot-demo)
2017-03-20 20:08:15.856  INFO 3888 --- [           main] com.concretepage.MyApplication           : No active profile set, falling back to default profiles: default
2017-03-20 20:08:15.955  INFO 3888 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@57f23557: startup date [Mon Mar 20 20:08:15 IST 2017]; root of context hierarchy
2017-03-20 20:08:17.833  INFO 3888 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8585 (http) 

References

Change the HTTP port

Customizing embedded servlet containers

В этом посте будет обсуждаться, как изменить порт сервера для приложения Spring Boot для прослушивания HTTP-запросов.

По умолчанию встроенный сервер приложения Spring Boot прослушивает HTTP-запросы на порту. 8080. Если ваше приложение не запускается на порту 8080, это означает, что порт уже используется, и мы получим специальное сообщение об ошибке, подобное показанному ниже:

***************************
APPLICATION FAILED TO START
***************************

Description:

The embedded servlet container failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port.

Мы можем решить эту проблему, изменив порт нашего приложения. Есть несколько способов добиться этого, как описано ниже:

1. Файл свойств

В Spring Boot мы можем установить порт сервера в application.properties находится в /src/main/resources/ каталог, как показано в следующем примере:

2. YAML-файл

Мы также можем хранить внешние свойства в файле YAML, который является надмножеством JSON. Создайте файл с именем application.yml и поместите его в корень пути к классам. Предыдущий пример соответствует следующему файлу YAML:

 
Оба application.properties а также application.yml может быть размещен в четырех заранее определенных местах:

  1. корень пути к классам
  2. Текущий каталог
  3. упаковка /config в пути к классам
  4. /config подкаталог текущего каталога

3. Системное свойство

Мы также можем установить server.port в качестве System свойство внутри основного метода, как показано ниже:

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class Main

{

    public static void main(String[] args)

    {

        System.setProperty(«server.port», «8081»);

        // или используйте

        // System.getProperties().put(«server.port», 8081);

        SpringApplication.run(Main.class, args);

    }

}

4. Изменить параметры виртуальной машины

Мы также можем определить системное свойство JVM при запуске приложения Spring Boot через аргумент командной строки, как показано ниже:

java Dserver.port=8081 jar springBootApp.jar

 
Здесь, springBootApp.jar наш исполняемый JAR. В противном случае в IntelliJ IDEA перейдите в «Выполнить» -> «Редактировать конфигурации» -> «Параметры виртуальной машины» и добавьте следующий аргумент в виртуальную машину.

 
Мы также можем передать свойство server.port в качестве аргумента приложения, как показано ниже:

java jar springBootApp.jar server.port=8081

5. Определите переменную среды ОС

Мы также можем использовать SERVER_PORT как переменная среды ОС в Unix/windows. Это работает, поскольку Spring Boot использует некоторые упрощенные правила для привязки свойств среды к @ConfigurationProperties бобы.

 
1. Окна

SET SERVER_PORT=8081

java jar springBootApp.jar

 
2. ЮНИКС

SERVER_PORT=8081 Java jar springBootApp.jar

 
Мы также можем настроить порт контейнера сервлетов программно:

1. До Spring Boot 2 мы могли использовать EmbeddedServletContainerCustomizer интерфейс.

import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;

import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;

@Component

public class CustomContainer implements EmbeddedServletContainerCustomizer {

    @Override

    public void customize(ConfigurableEmbeddedServletContainer container) {

        container.setPort(8081);

    }

}

 
2. С Spring Boot 2 EmbeddedServletContainerCustomizer интерфейс заменен на WebServerFactoryCustomizer,

import org.springframework.boot.web.server.WebServerFactoryCustomizer;

import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;

public class ServletConfig implements

        WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    public void customize(ConfigurableServletWebServerFactory factory) {

        factory.setPort(8081);

    }

}

 
Советы:

Для полного отключения конечных точек HTTP используйте server.port=-1. Это все равно создаст WebApplicationContext и может быть полезно для тестирования.

Чтобы назначить случайный порт HTTP, используйте server.port=0. Чтобы обнаружить случайный HTTP-порт во время выполнения, используйте @Value("${local.server.port}").

Это все о настройке порта в приложении Spring Boot.

Спасибо за чтение.

Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.

Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования 🙂

This section provides answers to some common ‘how do I do that…​’ questions that often arise when using Spring Boot.
Its coverage is not exhaustive, but it does cover quite a lot.

If you have a specific problem that we do not cover here, you might want to check stackoverflow.com to see if someone has already provided an answer.
This is also a great place to ask new questions (please use the spring-boot tag).

We are also more than happy to extend this section.
If you want to add a ‘how-to’, send us a pull request.

1. Spring Boot Application

This section includes topics relating directly to Spring Boot applications.

1.1. Create Your Own FailureAnalyzer

FailureAnalyzer is a great way to intercept an exception on startup and turn it into a human-readable message, wrapped in a FailureAnalysis.
Spring Boot provides such an analyzer for application-context-related exceptions, JSR-303 validations, and more.
You can also create your own.

AbstractFailureAnalyzer is a convenient extension of FailureAnalyzer that checks the presence of a specified exception type in the exception to handle.
You can extend from that so that your implementation gets a chance to handle the exception only when it is actually present.
If, for whatever reason, you cannot handle the exception, return null to give another implementation a chance to handle the exception.

FailureAnalyzer implementations must be registered in META-INF/spring.factories.
The following example registers ProjectConstraintViolationFailureAnalyzer:

org.springframework.boot.diagnostics.FailureAnalyzer=
com.example.ProjectConstraintViolationFailureAnalyzer
If you need access to the BeanFactory or the Environment, your FailureAnalyzer can implement BeanFactoryAware or EnvironmentAware respectively.

1.2. Troubleshoot Auto-configuration

The Spring Boot auto-configuration tries its best to “do the right thing”, but sometimes things fail, and it can be hard to tell why.

There is a really useful ConditionEvaluationReport available in any Spring Boot ApplicationContext.
You can see it if you enable DEBUG logging output.
If you use the spring-boot-actuator (see the Actuator chapter), there is also a conditions endpoint that renders the report in JSON.
Use that endpoint to debug the application and see what features have been added (and which have not been added) by Spring Boot at runtime.

Many more questions can be answered by looking at the source code and the Javadoc.
When reading the code, remember the following rules of thumb:

  • Look for classes called *AutoConfiguration and read their sources.
    Pay special attention to the @Conditional* annotations to find out what features they enable and when.
    Add --debug to the command line or a System property -Ddebug to get a log on the console of all the auto-configuration decisions that were made in your app.
    In a running application with actuator enabled, look at the conditions endpoint (/actuator/conditions or the JMX equivalent) for the same information.

  • Look for classes that are @ConfigurationProperties (such as ServerProperties) and read from there the available external configuration options.
    The @ConfigurationProperties annotation has a name attribute that acts as a prefix to external properties.
    Thus, ServerProperties has prefix="server" and its configuration properties are server.port, server.address, and others.
    In a running application with actuator enabled, look at the configprops endpoint.

  • Look for uses of the bind method on the Binder to pull configuration values explicitly out of the Environment in a relaxed manner.
    It is often used with a prefix.

  • Look for @Value annotations that bind directly to the Environment.

  • Look for @ConditionalOnExpression annotations that switch features on and off in response to SpEL expressions, normally evaluated with placeholders resolved from the Environment.

1.3. Customize the Environment or ApplicationContext Before It Starts

A SpringApplication has ApplicationListeners and ApplicationContextInitializers that are used to apply customizations to the context or environment.
Spring Boot loads a number of such customizations for use internally from META-INF/spring.factories.
There is more than one way to register additional customizations:

  • Programmatically, per application, by calling the addListeners and addInitializers methods on SpringApplication before you run it.

  • Declaratively, per application, by setting the context.initializer.classes or context.listener.classes properties.

  • Declaratively, for all applications, by adding a META-INF/spring.factories and packaging a jar file that the applications all use as a library.

The SpringApplication sends some special ApplicationEvents to the listeners (some even before the context is created) and then registers the listeners for events published by the ApplicationContext as well.
See “Application Events and Listeners” in the ‘Spring Boot features’ section for a complete list.

It is also possible to customize the Environment before the application context is refreshed by using EnvironmentPostProcessor.
Each implementation should be registered in META-INF/spring.factories, as shown in the following example:

org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor

The implementation can load arbitrary files and add them to the Environment.
For instance, the following example loads a YAML configuration file from the classpath:

Java

import java.io.IOException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;

public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {

    private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Resource path = new ClassPathResource("com/example/myapp/config.yml");
        PropertySource<?> propertySource = loadYaml(path);
        environment.getPropertySources().addLast(propertySource);
    }

    private PropertySource<?> loadYaml(Resource path) {
        Assert.isTrue(path.exists(), () -> "Resource " + path + " does not exist");
        try {
            return this.loader.load("custom-resource", path).get(0);
        }
        catch (IOException ex) {
            throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
        }
    }

}

Kotlin

import org.springframework.boot.SpringApplication
import org.springframework.boot.env.EnvironmentPostProcessor
import org.springframework.boot.env.YamlPropertySourceLoader
import org.springframework.core.env.ConfigurableEnvironment
import org.springframework.core.env.PropertySource
import org.springframework.core.io.ClassPathResource
import org.springframework.core.io.Resource
import org.springframework.util.Assert
import java.io.IOException

class MyEnvironmentPostProcessor : EnvironmentPostProcessor {

    private val loader = YamlPropertySourceLoader()

    override fun postProcessEnvironment(environment: ConfigurableEnvironment, application: SpringApplication) {
        val path: Resource = ClassPathResource("com/example/myapp/config.yml")
        val propertySource = loadYaml(path)
        environment.propertySources.addLast(propertySource)
    }

    private fun loadYaml(path: Resource): PropertySource<*> {
        Assert.isTrue(path.exists()) { "Resource $path does not exist" }
        return try {
            loader.load("custom-resource", path)[0]
        } catch (ex: IOException) {
            throw IllegalStateException("Failed to load yaml configuration from $path", ex)
        }
    }

}
The Environment has already been prepared with all the usual property sources that Spring Boot loads by default.
It is therefore possible to get the location of the file from the environment.
The preceding example adds the custom-resource property source at the end of the list so that a key defined in any of the usual other locations takes precedence.
A custom implementation may define another order.
While using @PropertySource on your @SpringBootApplication may seem to be a convenient way to load a custom resource in the Environment, we do not recommend it.
Such property sources are not added to the Environment until the application context is being refreshed.
This is too late to configure certain properties such as logging.* and spring.main.* which are read before refresh begins.

1.4. Build an ApplicationContext Hierarchy (Adding a Parent or Root Context)

You can use the ApplicationBuilder class to create parent/child ApplicationContext hierarchies.
See “features.html” in the ‘Spring Boot features’ section for more information.

1.5. Create a Non-web Application

Not all Spring applications have to be web applications (or web services).
If you want to execute some code in a main method but also bootstrap a Spring application to set up the infrastructure to use, you can use the SpringApplication features of Spring Boot.
A SpringApplication changes its ApplicationContext class, depending on whether it thinks it needs a web application or not.
The first thing you can do to help it is to leave server-related dependencies (such as the servlet API) off the classpath.
If you cannot do that (for example, you run two applications from the same code base) then you can explicitly call setWebApplicationType(WebApplicationType.NONE) on your SpringApplication instance or set the applicationContextClass property (through the Java API or with external properties).
Application code that you want to run as your business logic can be implemented as a CommandLineRunner and dropped into the context as a @Bean definition.

2. Properties and Configuration

This section includes topics about setting and reading properties and configuration settings and their interaction with Spring Boot applications.

2.1. Automatically Expand Properties at Build Time

Rather than hardcoding some properties that are also specified in your project’s build configuration, you can automatically expand them by instead using the existing build configuration.
This is possible in both Maven and Gradle.

2.1.1. Automatic Property Expansion Using Maven

You can automatically expand properties from the Maven project by using resource filtering.
If you use the spring-boot-starter-parent, you can then refer to your Maven ‘project properties’ with @[email protected] placeholders, as shown in the following example:

Only production configuration is filtered that way (in other words, no filtering is applied on src/test/resources).
If you enable the addResources flag, the spring-boot:run goal can add src/main/resources directly to the classpath (for hot reloading purposes).
Doing so circumvents the resource filtering and this feature.
Instead, you can use the exec:java goal or customize the plugin’s configuration.
See the plugin usage page for more details.

If you do not use the starter parent, you need to include the following element inside the <build/> element of your pom.xml:

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
    </resource>
</resources>

You also need to include the following element inside <plugins/>:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.7</version>
    <configuration>
        <delimiters>
            <delimiter>@</delimiter>
        </delimiters>
        <useDefaultDelimiters>false</useDefaultDelimiters>
    </configuration>
</plugin>
The useDefaultDelimiters property is important if you use standard Spring placeholders (such as ${placeholder}) in your configuration.
If that property is not set to false, these may be expanded by the build.

2.1.2. Automatic Property Expansion Using Gradle

You can automatically expand properties from the Gradle project by configuring the Java plugin’s processResources task to do so, as shown in the following example:

tasks.named('processResources') {
    expand(project.properties)
}

You can then refer to your Gradle project’s properties by using placeholders, as shown in the following example:

Properties

app.name=${name}
app.description=${description}

Yaml

app:
  name: "${name}"
  description: "${description}"
Gradle’s expand method uses Groovy’s SimpleTemplateEngine, which transforms ${..} tokens.
The ${..} style conflicts with Spring’s own property placeholder mechanism.
To use Spring property placeholders together with automatic expansion, escape the Spring property placeholders as follows: ${..}.

2.2. Externalize the Configuration of SpringApplication

A SpringApplication has bean property setters, so you can use its Java API as you create the application to modify its behavior.
Alternatively, you can externalize the configuration by setting properties in spring.main.*.
For example, in application.properties, you might have the following settings:

Properties

spring.main.web-application-type=none
spring.main.banner-mode=off

Yaml

spring:
  main:
    web-application-type: "none"
    banner-mode: "off"

Then the Spring Boot banner is not printed on startup, and the application is not starting an embedded web server.

Properties defined in external configuration override and replace the values specified with the Java API, with the notable exception of the primary sources.
Primary sources are those provided to the SpringApplication constructor:

Java

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

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(MyApplication.class);
        application.setBannerMode(Banner.Mode.OFF);
        application.run(args);
    }

}

Kotlin

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

@SpringBootApplication
object MyApplication {

    @JvmStatic
    fun main(args: Array<String>) {
        val application = SpringApplication(MyApplication::class.java)
        application.setBannerMode(Banner.Mode.OFF)
        application.run(*args)
    }

}

Or to sources(…​) method of a SpringApplicationBuilder:

Java

import org.springframework.boot.Banner;
import org.springframework.boot.builder.SpringApplicationBuilder;

public class MyApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder()
            .bannerMode(Banner.Mode.OFF)
            .sources(MyApplication.class)
            .run(args);
    }

}

Kotlin

import org.springframework.boot.Banner
import org.springframework.boot.builder.SpringApplicationBuilder

object MyApplication {

    @JvmStatic
    fun main(args: Array<String>) {
        SpringApplicationBuilder()
            .bannerMode(Banner.Mode.OFF)
            .sources(MyApplication::class.java)
            .run(*args)
    }

}

Given the examples above, if we have the following configuration:

Properties

spring.main.sources=com.example.MyDatabaseConfig,com.example.MyJmsConfig
spring.main.banner-mode=console

Yaml

spring:
  main:
    sources: "com.example.MyDatabaseConfig,com.example.MyJmsConfig"
    banner-mode: "console"

The actual application will show the banner (as overridden by configuration) and uses three sources for the ApplicationContext.
The application sources are:

  1. MyApplication (from the code)

  2. MyDatabaseConfig (from the external config)

  3. MyJmsConfig(from the external config)

2.3. Change the Location of External Properties of an Application

By default, properties from different sources are added to the Spring Environment in a defined order (see “features.html” in the ‘Spring Boot features’ section for the exact order).

You can also provide the following System properties (or environment variables) to change the behavior:

  • spring.config.name (SPRING_CONFIG_NAME): Defaults to application as the root of the file name.

  • spring.config.location (SPRING_CONFIG_LOCATION): The file to load (such as a classpath resource or a URL).
    A separate Environment property source is set up for this document and it can be overridden by system properties, environment variables, or the command line.

No matter what you set in the environment, Spring Boot always loads application.properties as described above.
By default, if YAML is used, then files with the ‘.yml’ extension are also added to the list.

If you want detailed information about the files that are being loaded you can set the logging level of org.springframework.boot.context.config to trace.

2.4. Use ‘Short’ Command Line Arguments

Some people like to use (for example) --port=9000 instead of --server.port=9000 to set configuration properties on the command line.
You can enable this behavior by using placeholders in application.properties, as shown in the following example:

Yaml

server:
  port: "${port:8080}"
If you inherit from the spring-boot-starter-parent POM, the default filter token of the maven-resources-plugins has been changed from ${*} to @ (that is, @[email protected] instead of ${maven.token}) to prevent conflicts with Spring-style placeholders.
If you have enabled Maven filtering for the application.properties directly, you may want to also change the default filter token to use other delimiters.
In this specific case, the port binding works in a PaaS environment such as Heroku or Cloud Foundry.
In those two platforms, the PORT environment variable is set automatically and Spring can bind to capitalized synonyms for Environment properties.

2.5. Use YAML for External Properties

YAML is a superset of JSON and, as such, is a convenient syntax for storing external properties in a hierarchical format, as shown in the following example:

spring:
  application:
    name: "cruncher"
  datasource:
    driver-class-name: "com.mysql.jdbc.Driver"
    url: "jdbc:mysql://localhost/test"
server:
  port: 9000

Create a file called application.yml and put it in the root of your classpath.
Then add snakeyaml to your dependencies (Maven coordinates org.yaml:snakeyaml, already included if you use the spring-boot-starter).
A YAML file is parsed to a Java Map<String,Object> (like a JSON object), and Spring Boot flattens the map so that it is one level deep and has period-separated keys, as many people are used to with Properties files in Java.

The preceding example YAML corresponds to the following application.properties file:

spring.application.name=cruncher
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost/test
server.port=9000

See “features.html” in the ‘Spring Boot features’ section for more information about YAML.

2.6. Set the Active Spring Profiles

The Spring Environment has an API for this, but you would normally set a System property (spring.profiles.active) or an OS environment variable (SPRING_PROFILES_ACTIVE).
Also, you can launch your application with a -D argument (remember to put it before the main class or jar archive), as follows:

$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar

In Spring Boot, you can also set the active profile in application.properties, as shown in the following example:

Properties

spring.profiles.active=production

Yaml

spring:
  profiles:
    active: "production"

A value set this way is replaced by the System property or environment variable setting but not by the SpringApplicationBuilder.profiles() method.
Thus, the latter Java API can be used to augment the profiles without changing the defaults.

See “features.html” in the “Spring Boot features” section for more information.

2.7. Set the Default Profile Name

The default profile is a profile that is enabled if no profile is active.
By default, the name of the default profile is default, but it could be changed using a System property (spring.profiles.default) or an OS environment variable (SPRING_PROFILES_DEFAULT).

In Spring Boot, you can also set the default profile name in application.properties, as shown in the following example:

Properties

spring.profiles.default=dev

Yaml

spring:
  profiles:
    default: "dev"

See “features.html” in the “Spring Boot features” section for more information.

2.8. Change Configuration Depending on the Environment

Spring Boot supports multi-document YAML and Properties files (see features.html for details) which can be activated conditionally based on the active profiles.

If a document contains a spring.config.activate.on-profile key, then the profiles value (a comma-separated list of profiles or a profile expression) is fed into the Spring Environment.acceptsProfiles() method.
If the profile expression matches then that document is included in the final merge (otherwise, it is not), as shown in the following example:

Properties

server.port=9000
#---
spring.config.activate.on-profile=development
server.port=9001
#---
spring.config.activate.on-profile=production
server.port=0

Yaml

server:
  port: 9000
---
spring:
  config:
    activate:
      on-profile: "development"
server:
  port: 9001
---
spring:
  config:
    activate:
      on-profile: "production"
server:
  port: 0

In the preceding example, the default port is 9000.
However, if the Spring profile called ‘development’ is active, then the port is 9001.
If ‘production’ is active, then the port is 0.

The documents are merged in the order in which they are encountered.
Later values override earlier values.

2.9. Discover Built-in Options for External Properties

Spring Boot binds external properties from application.properties (or .yml files and other places) into an application at runtime.
There is not (and technically cannot be) an exhaustive list of all supported properties in a single location, because contributions can come from additional jar files on your classpath.

A running application with the Actuator features has a configprops endpoint that shows all the bound and bindable properties available through @ConfigurationProperties.

The appendix includes an application.properties example with a list of the most common properties supported by Spring Boot.
The definitive list comes from searching the source code for @ConfigurationProperties and @Value annotations as well as the occasional use of Binder.
For more about the exact ordering of loading properties, see «features.html».

3. Embedded Web Servers

Each Spring Boot web application includes an embedded web server.
This feature leads to a number of how-to questions, including how to change the embedded server and how to configure the embedded server.
This section answers those questions.

3.1. Use Another Web Server

Many Spring Boot starters include default embedded containers.

  • For servlet stack applications, the spring-boot-starter-web includes Tomcat by including spring-boot-starter-tomcat, but you can use spring-boot-starter-jetty or spring-boot-starter-undertow instead.

  • For reactive stack applications, the spring-boot-starter-webflux includes Reactor Netty by including spring-boot-starter-reactor-netty, but you can use spring-boot-starter-tomcat, spring-boot-starter-jetty, or spring-boot-starter-undertow instead.

When switching to a different HTTP server, you need to swap the default dependencies for those that you need instead.
To help with this process, Spring Boot provides a separate starter for each of the supported HTTP servers.

The following Maven example shows how to exclude Tomcat and include Jetty for Spring MVC:

<properties>
    <servlet-api.version>3.1.0</servlet-api.version>
</properties>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <!-- Exclude the Tomcat dependency -->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
The version of the servlet API has been overridden as, unlike Tomcat 9 and Undertow 2, Jetty 9.4 does not support servlet 4.0.

If you wish to use Jetty 10, which does support servlet 4.0, you can do so as shown in the following example:

<properties>
    <jetty.version>10.0.8</jetty.version>
</properties>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <!-- Exclude the Tomcat dependency -->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
    <exclusions>
        <!-- Exclude the Jetty-9 specific dependencies -->
        <exclusion>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>websocket-server</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>javax-websocket-server-impl</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Note that along with excluding the Tomcat starter, a couple of Jetty9-specific dependencies also need to be excluded.

The following Gradle example configures the necessary dependencies and a module replacement to use Undertow in place of Reactor Netty for Spring WebFlux:

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-undertow"
    implementation "org.springframework.boot:spring-boot-starter-webflux"
    modules {
        module("org.springframework.boot:spring-boot-starter-reactor-netty") {
            replacedBy("org.springframework.boot:spring-boot-starter-undertow", "Use Undertow instead of Reactor Netty")
        }
    }
}
spring-boot-starter-reactor-netty is required to use the WebClient class, so you may need to keep a dependency on Netty even when you need to include a different HTTP server.

3.2. Disabling the Web Server

If your classpath contains the necessary bits to start a web server, Spring Boot will automatically start it.
To disable this behavior configure the WebApplicationType in your application.properties, as shown in the following example:

Properties

spring.main.web-application-type=none

Yaml

spring:
  main:
    web-application-type: "none"

3.3. Change the HTTP Port

In a standalone application, the main HTTP port defaults to 8080 but can be set with server.port (for example, in application.properties or as a System property).
Thanks to relaxed binding of Environment values, you can also use SERVER_PORT (for example, as an OS environment variable).

To switch off the HTTP endpoints completely but still create a WebApplicationContext, use server.port=-1 (doing so is sometimes useful for testing).

For more details, see “web.html” in the ‘Spring Boot Features’ section, or the ServerProperties source code.

3.4. Use a Random Unassigned HTTP Port

To scan for a free port (using OS natives to prevent clashes) use server.port=0.

3.5. Discover the HTTP Port at Runtime

You can access the port the server is running on from log output or from the WebServerApplicationContext through its WebServer.
The best way to get that and be sure it has been initialized is to add a @Bean of type ApplicationListener<WebServerInitializedEvent> and pull the container out of the event when it is published.

Tests that use @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) can also inject the actual port into a field by using the @LocalServerPort annotation, as shown in the following example:

Java

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MyWebIntegrationTests {

    @LocalServerPort
    int port;

    // ...

}

Kotlin

import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.test.web.server.LocalServerPort

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyWebIntegrationTests {

    @LocalServerPort
    var port = 0

    // ...

}

@LocalServerPort is a meta-annotation for @Value("${local.server.port}").
Do not try to inject the port in a regular application.
As we just saw, the value is set only after the container has been initialized.
Contrary to a test, application code callbacks are processed early (before the value is actually available).

3.6. Enable HTTP Response Compression

HTTP response compression is supported by Jetty, Tomcat, Reactor Netty, and Undertow.
It can be enabled in application.properties, as follows:

Properties

server.compression.enabled=true

Yaml

server:
  compression:
    enabled: true

By default, responses must be at least 2048 bytes in length for compression to be performed.
You can configure this behavior by setting the server.compression.min-response-size property.

By default, responses are compressed only if their content type is one of the following:

  • text/html

  • text/xml

  • text/plain

  • text/css

  • text/javascript

  • application/javascript

  • application/json

  • application/xml

You can configure this behavior by setting the server.compression.mime-types property.

3.7. Configure SSL

SSL can be configured declaratively by setting the various server.ssl.* properties, typically in application.properties or application.yml.
The following example shows setting SSL properties using a Java KeyStore file:

Properties

server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=another-secret

Yaml

server:
  port: 8443
  ssl:
    key-store: "classpath:keystore.jks"
    key-store-password: "secret"
    key-password: "another-secret"

The following example shows setting SSL properties using PEM-encoded certificate and private key files:

Properties

server.port=8443
server.ssl.certificate=classpath:my-cert.crt
server.ssl.certificate-private-key=classpath:my-cert.key
server.ssl.trust-certificate=classpath:ca-cert.crt

Yaml

server:
  port: 8443
  ssl:
    certificate: "classpath:my-cert.crt"
    certificate-private-key: "classpath:my-cert.key"
    trust-certificate: "classpath:ca-cert.crt"

See Ssl for details of all of the supported properties.

Using configuration such as the preceding example means the application no longer supports a plain HTTP connector at port 8080.
Spring Boot does not support the configuration of both an HTTP connector and an HTTPS connector through application.properties.
If you want to have both, you need to configure one of them programmatically.
We recommend using application.properties to configure HTTPS, as the HTTP connector is the easier of the two to configure programmatically.

3.8. Configure HTTP/2

You can enable HTTP/2 support in your Spring Boot application with the server.http2.enabled configuration property.
Both h2 (HTTP/2 over TLS) and h2c (HTTP/2 over TCP) are supported.
To use h2, SSL must also be enabled.
When SSL is not enabled, h2c will be used.
You may, for example, want to use h2c when your application is running behind a proxy server that is performing TLS termination.

3.8.1. HTTP/2 With Tomcat

Spring Boot ships by default with Tomcat 10.1.x which supports h2c and h2 out of the box.
Alternatively, you can use libtcnative for h2 support if the library and its dependencies are installed on the host operating system.

The library directory must be made available, if not already, to the JVM library path.
You can do so with a JVM argument such as -Djava.library.path=/usr/local/opt/tomcat-native/lib.
More on this in the official Tomcat documentation.

3.8.2. HTTP/2 With Jetty

For HTTP/2 support, Jetty requires the additional org.eclipse.jetty.http2:http2-server dependency.
To use h2c no other dependencies are required.
To use h2, you also need to choose one of the following dependencies, depending on your deployment:

  • org.eclipse.jetty:jetty-alpn-java-server to use the JDK built-in support

  • org.eclipse.jetty:jetty-alpn-conscrypt-server and the Conscrypt library

3.8.3. HTTP/2 With Reactor Netty

The spring-boot-webflux-starter is using by default Reactor Netty as a server.
Reactor Netty supports h2c and h2 out of the box.
For optimal runtime performance, this server also supports h2 with native libraries.
To enable that, your application needs to have an additional dependency.

Spring Boot manages the version for the io.netty:netty-tcnative-boringssl-static «uber jar», containing native libraries for all platforms.
Developers can choose to import only the required dependencies using a classifier (see the Netty official documentation).

3.8.4. HTTP/2 With Undertow

Undertow supports h2c and h2 out of the box.

3.9. Configure the Web Server

Generally, you should first consider using one of the many available configuration keys and customize your web server by adding new entries in your application.properties or application.yml file.
See “Discover Built-in Options for External Properties”).
The server.* namespace is quite useful here, and it includes namespaces like server.tomcat.*, server.jetty.* and others, for server-specific features.
See the list of application-properties.html.

The previous sections covered already many common use cases, such as compression, SSL or HTTP/2.
However, if a configuration key does not exist for your use case, you should then look at WebServerFactoryCustomizer.
You can declare such a component and get access to the server factory relevant to your choice: you should select the variant for the chosen Server (Tomcat, Jetty, Reactor Netty, Undertow) and the chosen web stack (servlet or reactive).

The example below is for Tomcat with the spring-boot-starter-web (servlet stack):

Java

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        // customize the factory here
    }

}

Kotlin

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component

@Component
class MyTomcatWebServerCustomizer : WebServerFactoryCustomizer<TomcatServletWebServerFactory?> {

    override fun customize(factory: TomcatServletWebServerFactory?) {
        // customize the factory here
    }

}
Spring Boot uses that infrastructure internally to auto-configure the server.
Auto-configured WebServerFactoryCustomizer beans have an order of 0 and will be processed before any user-defined customizers, unless it has an explicit order that states otherwise.

Once you have got access to a WebServerFactory using the customizer, you can use it to configure specific parts, like connectors, server resources, or the server itself — all using server-specific APIs.

In addition Spring Boot provides:

Server Servlet stack Reactive stack

Tomcat

TomcatServletWebServerFactory

TomcatReactiveWebServerFactory

Jetty

JettyServletWebServerFactory

JettyReactiveWebServerFactory

Undertow

UndertowServletWebServerFactory

UndertowReactiveWebServerFactory

Reactor

N/A

NettyReactiveWebServerFactory

As a last resort, you can also declare your own WebServerFactory bean, which will override the one provided by Spring Boot.
When you do so, auto-configured customizers are still applied on your custom factory, so use that option carefully.

3.10. Add a Servlet, Filter, or Listener to an Application

In a servlet stack application, that is with the spring-boot-starter-web, there are two ways to add Servlet, Filter, ServletContextListener, and the other listeners supported by the Servlet API to your application:

  • Add a Servlet, Filter, or Listener by Using a Spring Bean

  • Add Servlets, Filters, and Listeners by Using Classpath Scanning

3.10.1. Add a Servlet, Filter, or Listener by Using a Spring Bean

To add a Servlet, Filter, or servlet *Listener by using a Spring bean, you must provide a @Bean definition for it.
Doing so can be very useful when you want to inject configuration or dependencies.
However, you must be very careful that they do not cause eager initialization of too many other beans, because they have to be installed in the container very early in the application lifecycle.
(For example, it is not a good idea to have them depend on your DataSource or JPA configuration.)
You can work around such restrictions by initializing the beans lazily when first used instead of on initialization.

In the case of filters and servlets, you can also add mappings and init parameters by adding a FilterRegistrationBean or a ServletRegistrationBean instead of or in addition to the underlying component.

If no dispatcherType is specified on a filter registration, REQUEST is used.
This aligns with the servlet specification’s default dispatcher type.

Like any other Spring bean, you can define the order of servlet filter beans; please make sure to check the “web.html” section.

Disable Registration of a Servlet or Filter

As described earlier, any Servlet or Filter beans are registered with the servlet container automatically.
To disable registration of a particular Filter or Servlet bean, create a registration bean for it and mark it as disabled, as shown in the following example:

Java

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyFilterConfiguration {

    @Bean
    public FilterRegistrationBean<MyFilter> registration(MyFilter filter) {
        FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(filter);
        registration.setEnabled(false);
        return registration;
    }

}

Kotlin

import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyFilterConfiguration {

    @Bean
    fun registration(filter: MyFilter): FilterRegistrationBean<MyFilter> {
        val registration = FilterRegistrationBean(filter)
        registration.isEnabled = false
        return registration
    }

}

3.10.2. Add Servlets, Filters, and Listeners by Using Classpath Scanning

@WebServlet, @WebFilter, and @WebListener annotated classes can be automatically registered with an embedded servlet container by annotating a @Configuration class with @ServletComponentScan and specifying the package(s) containing the components that you want to register.
By default, @ServletComponentScan scans from the package of the annotated class.

3.11. Configure Access Logging

Access logs can be configured for Tomcat, Undertow, and Jetty through their respective namespaces.

For instance, the following settings log access on Tomcat with a custom pattern.

Properties

server.tomcat.basedir=my-tomcat
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a %r %s (%D ms)

Yaml

server:
  tomcat:
    basedir: "my-tomcat"
    accesslog:
      enabled: true
      pattern: "%t %a %r %s (%D ms)"
The default location for logs is a logs directory relative to the Tomcat base directory.
By default, the logs directory is a temporary directory, so you may want to fix Tomcat’s base directory or use an absolute path for the logs.
In the preceding example, the logs are available in my-tomcat/logs relative to the working directory of the application.

Access logging for Undertow can be configured in a similar fashion, as shown in the following example:

Properties

server.undertow.accesslog.enabled=true
server.undertow.accesslog.pattern=%t %a %r %s (%D ms)
server.undertow.options.server.record-request-start-time=true

Yaml

server:
  undertow:
    accesslog:
      enabled: true
      pattern: "%t %a %r %s (%D ms)"
    options:
      server:
        record-request-start-time: true

Note that, in addition to enabling access logging and configuring its pattern, recording request start times has also been enabled.
This is required when including the response time (%D) in the access log pattern.
Logs are stored in a logs directory relative to the working directory of the application.
You can customize this location by setting the server.undertow.accesslog.dir property.

Finally, access logging for Jetty can also be configured as follows:

Properties

server.jetty.accesslog.enabled=true
server.jetty.accesslog.filename=/var/log/jetty-access.log

Yaml

server:
  jetty:
    accesslog:
      enabled: true
      filename: "/var/log/jetty-access.log"

By default, logs are redirected to System.err.
For more details, see the Jetty documentation.

3.12. Running Behind a Front-end Proxy Server

If your application is running behind a proxy, a load-balancer or in the cloud, the request information (like the host, port, scheme…​) might change along the way.
Your application may be running on 10.10.10.10:8080, but HTTP clients should only see example.org.

RFC7239 «Forwarded Headers» defines the Forwarded HTTP header; proxies can use this header to provide information about the original request.
You can configure your application to read those headers and automatically use that information when creating links and sending them to clients in HTTP 302 responses, JSON documents or HTML pages.
There are also non-standard headers, like X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Proto, X-Forwarded-Ssl, and X-Forwarded-Prefix.

If the proxy adds the commonly used X-Forwarded-For and X-Forwarded-Proto headers, setting server.forward-headers-strategy to NATIVE is enough to support those.
With this option, the Web servers themselves natively support this feature; you can check their specific documentation to learn about specific behavior.

If this is not enough, Spring Framework provides a ForwardedHeaderFilter.
You can register it as a servlet filter in your application by setting server.forward-headers-strategy is set to FRAMEWORK.

If you are using Tomcat and terminating SSL at the proxy, server.tomcat.redirect-context-root should be set to false.
This allows the X-Forwarded-Proto header to be honored before any redirects are performed.
If your application runs in Cloud Foundry or Heroku, the server.forward-headers-strategy property defaults to NATIVE.
In all other instances, it defaults to NONE.

3.12.1. Customize Tomcat’s Proxy Configuration

If you use Tomcat, you can additionally configure the names of the headers used to carry “forwarded” information, as shown in the following example:

Properties

server.tomcat.remoteip.remote-ip-header=x-your-remote-ip-header
server.tomcat.remoteip.protocol-header=x-your-protocol-header

Yaml

server:
  tomcat:
    remoteip:
      remote-ip-header: "x-your-remote-ip-header"
      protocol-header: "x-your-protocol-header"

Tomcat is also configured with a regular expression that matches internal proxies that are to be trusted.
See the server.tomcat.remoteip.internal-proxies entry in the appendix for its default value.
You can customize the valve’s configuration by adding an entry to application.properties, as shown in the following example:

Properties

server.tomcat.remoteip.internal-proxies=192\.168\.\d{1,3}\.\d{1,3}

Yaml

server:
  tomcat:
    remoteip:
      internal-proxies: "192\.168\.\d{1,3}\.\d{1,3}"
You can trust all proxies by setting the internal-proxies to empty (but do not do so in production).

You can take complete control of the configuration of Tomcat’s RemoteIpValve by switching the automatic one off (to do so, set server.forward-headers-strategy=NONE) and adding a new valve instance using a WebServerFactoryCustomizer bean.

3.13. Enable Multiple Connectors with Tomcat

You can add an org.apache.catalina.connector.Connector to the TomcatServletWebServerFactory, which can allow multiple connectors, including HTTP and HTTPS connectors, as shown in the following example:

Java

import org.apache.catalina.connector.Connector;

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyTomcatConfiguration {

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> connectorCustomizer() {
        return (tomcat) -> tomcat.addAdditionalTomcatConnectors(createConnector());
    }

    private Connector createConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setPort(8081);
        return connector;
    }

}

Kotlin

import org.apache.catalina.connector.Connector
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyTomcatConfiguration {

    @Bean
    fun connectorCustomizer(): WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
        return WebServerFactoryCustomizer { tomcat: TomcatServletWebServerFactory ->
            tomcat.addAdditionalTomcatConnectors(
                createConnector()
            )
        }
    }

    private fun createConnector(): Connector {
        val connector = Connector("org.apache.coyote.http11.Http11NioProtocol")
        connector.port = 8081
        return connector
    }

}

3.14. Enable Tomcat’s MBean Registry

Embedded Tomcat’s MBean registry is disabled by default.
This minimizes Tomcat’s memory footprint.
If you want to use Tomcat’s MBeans, for example so that they can be used by Micrometer to expose metrics, you must use the server.tomcat.mbeanregistry.enabled property to do so, as shown in the following example:

Properties

server.tomcat.mbeanregistry.enabled=true

Yaml

server:
  tomcat:
    mbeanregistry:
      enabled: true

3.15. Enable Multiple Listeners with Undertow

Add an UndertowBuilderCustomizer to the UndertowServletWebServerFactory and add a listener to the Builder, as shown in the following example:

Java

import io.undertow.Undertow.Builder;

import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyUndertowConfiguration {

    @Bean
    public WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowListenerCustomizer() {
        return (factory) -> factory.addBuilderCustomizers(this::addHttpListener);
    }

    private Builder addHttpListener(Builder builder) {
        return builder.addHttpListener(8080, "0.0.0.0");
    }

}

Kotlin

import io.undertow.Undertow
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyUndertowConfiguration {

    @Bean
    fun undertowListenerCustomizer(): WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
        return WebServerFactoryCustomizer { factory: UndertowServletWebServerFactory ->
            factory.addBuilderCustomizers(
                UndertowBuilderCustomizer { builder: Undertow.Builder -> addHttpListener(builder) })
        }
    }

    private fun addHttpListener(builder: Undertow.Builder): Undertow.Builder {
        return builder.addHttpListener(8080, "0.0.0.0")
    }

}

3.16. Create WebSocket Endpoints Using @ServerEndpoint

If you want to use @ServerEndpoint in a Spring Boot application that used an embedded container, you must declare a single ServerEndpointExporter @Bean, as shown in the following example:

Java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration(proxyBeanMethods = false)
public class MyWebSocketConfiguration {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

Kotlin

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.socket.server.standard.ServerEndpointExporter

@Configuration(proxyBeanMethods = false)
class MyWebSocketConfiguration {

    @Bean
    fun serverEndpointExporter(): ServerEndpointExporter {
        return ServerEndpointExporter()
    }

}

The bean shown in the preceding example registers any @ServerEndpoint annotated beans with the underlying WebSocket container.
When deployed to a standalone servlet container, this role is performed by a servlet container initializer, and the ServerEndpointExporter bean is not required.

4. Spring MVC

Spring Boot has a number of starters that include Spring MVC.
Note that some starters include a dependency on Spring MVC rather than include it directly.
This section answers common questions about Spring MVC and Spring Boot.

4.1. Write a JSON REST Service

Any Spring @RestController in a Spring Boot application should render JSON response by default as long as Jackson2 is on the classpath, as shown in the following example:

Java

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

@RestController
public class MyController {

    @RequestMapping("/thing")
    public MyThing thing() {
        return new MyThing();
    }

}

Kotlin

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

@RestController
class MyController {

    @RequestMapping("/thing")
    fun thing(): MyThing {
        return MyThing()
    }

}

As long as MyThing can be serialized by Jackson2 (true for a normal POJO or Groovy object), then localhost:8080/thing serves a JSON representation of it by default.
Note that, in a browser, you might sometimes see XML responses, because browsers tend to send accept headers that prefer XML.

4.2. Write an XML REST Service

If you have the Jackson XML extension (jackson-dataformat-xml) on the classpath, you can use it to render XML responses.
The previous example that we used for JSON would work.
To use the Jackson XML renderer, add the following dependency to your project:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

If Jackson’s XML extension is not available and JAXB is available, XML can be rendered with the additional requirement of having MyThing annotated as @XmlRootElement, as shown in the following example:

Java

import jakarta.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class MyThing {

    private String name;

    // getters/setters ...

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Kotlin

import jakarta.xml.bind.annotation.XmlRootElement

@XmlRootElement
class MyThing {

    var name: String? = null

}

You will need to ensure that the JAXB library is part of your project, for example by adding:

<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
</dependency>
To get the server to render XML instead of JSON, you might have to send an Accept: text/xml header (or use a browser).

4.3. Customize the Jackson ObjectMapper

Spring MVC (client and server side) uses HttpMessageConverters to negotiate content conversion in an HTTP exchange.
If Jackson is on the classpath, you already get the default converter(s) provided by Jackson2ObjectMapperBuilder, an instance of which is auto-configured for you.

The ObjectMapper (or XmlMapper for Jackson XML converter) instance (created by default) has the following customized properties:

  • MapperFeature.DEFAULT_VIEW_INCLUSION is disabled

  • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES is disabled

  • SerializationFeature.WRITE_DATES_AS_TIMESTAMPS is disabled

Spring Boot also has some features to make it easier to customize this behavior.

You can configure the ObjectMapper and XmlMapper instances by using the environment.
Jackson provides an extensive suite of on/off features that can be used to configure various aspects of its processing.
These features are described in six enums (in Jackson) that map onto properties in the environment:

Enum Property Values

com.fasterxml.jackson.databind.DeserializationFeature

spring.jackson.deserialization.<feature_name>

true, false

com.fasterxml.jackson.core.JsonGenerator.Feature

spring.jackson.generator.<feature_name>

true, false

com.fasterxml.jackson.databind.MapperFeature

spring.jackson.mapper.<feature_name>

true, false

com.fasterxml.jackson.core.JsonParser.Feature

spring.jackson.parser.<feature_name>

true, false

com.fasterxml.jackson.databind.SerializationFeature

spring.jackson.serialization.<feature_name>

true, false

com.fasterxml.jackson.annotation.JsonInclude.Include

spring.jackson.default-property-inclusion

always, non_null, non_absent, non_default, non_empty

For example, to enable pretty print, set spring.jackson.serialization.indent_output=true.
Note that, thanks to the use of relaxed binding, the case of indent_output does not have to match the case of the corresponding enum constant, which is INDENT_OUTPUT.

This environment-based configuration is applied to the auto-configured Jackson2ObjectMapperBuilder bean and applies to any mappers created by using the builder, including the auto-configured ObjectMapper bean.

The context’s Jackson2ObjectMapperBuilder can be customized by one or more Jackson2ObjectMapperBuilderCustomizer beans.
Such customizer beans can be ordered (Boot’s own customizer has an order of 0), letting additional customization be applied both before and after Boot’s customization.

Any beans of type com.fasterxml.jackson.databind.Module are automatically registered with the auto-configured Jackson2ObjectMapperBuilder and are applied to any ObjectMapper instances that it creates.
This provides a global mechanism for contributing custom modules when you add new features to your application.

If you want to replace the default ObjectMapper completely, either define a @Bean of that type and mark it as @Primary or, if you prefer the builder-based approach, define a Jackson2ObjectMapperBuilder @Bean.
Note that, in either case, doing so disables all auto-configuration of the ObjectMapper.

If you provide any @Beans of type MappingJackson2HttpMessageConverter, they replace the default value in the MVC configuration.
Also, a convenience bean of type HttpMessageConverters is provided (and is always available if you use the default MVC configuration).
It has some useful methods to access the default and user-enhanced message converters.

4.4. Customize the @ResponseBody Rendering

Spring uses HttpMessageConverters to render @ResponseBody (or responses from @RestController).
You can contribute additional converters by adding beans of the appropriate type in a Spring Boot context.
If a bean you add is of a type that would have been included by default anyway (such as MappingJackson2HttpMessageConverter for JSON conversions), it replaces the default value.
A convenience bean of type HttpMessageConverters is provided and is always available if you use the default MVC configuration.
It has some useful methods to access the default and user-enhanced message converters (For example, it can be useful if you want to manually inject them into a custom RestTemplate).

As in normal MVC usage, any WebMvcConfigurer beans that you provide can also contribute converters by overriding the configureMessageConverters method.
However, unlike with normal MVC, you can supply only additional converters that you need (because Spring Boot uses the same mechanism to contribute its defaults).
Finally, if you opt out of the Spring Boot default MVC configuration by providing your own @EnableWebMvc configuration, you can take control completely and do everything manually by using getMessageConverters from WebMvcConfigurationSupport.

4.5. Handling Multipart File Uploads

Spring Boot embraces the servlet 5 jakarta.servlet.http.Part API to support uploading files.
By default, Spring Boot configures Spring MVC with a maximum size of 1MB per file and a maximum of 10MB of file data in a single request.
You may override these values, the location to which intermediate data is stored (for example, to the /tmp directory), and the threshold past which data is flushed to disk by using the properties exposed in the MultipartProperties class.
For example, if you want to specify that files be unlimited, set the spring.servlet.multipart.max-file-size property to -1.

The multipart support is helpful when you want to receive multipart encoded file data as a @RequestParam-annotated parameter of type MultipartFile in a Spring MVC controller handler method.

It is recommended to use the container’s built-in support for multipart uploads rather than introducing an additional dependency such as Apache Commons File Upload.

4.6. Switch Off the Spring MVC DispatcherServlet

By default, all content is served from the root of your application (/).
If you would rather map to a different path, you can configure one as follows:

Properties

spring.mvc.servlet.path=/mypath

Yaml

spring:
  mvc:
    servlet:
      path: "/mypath"

If you have additional servlets you can declare a @Bean of type Servlet or ServletRegistrationBean for each and Spring Boot will register them transparently to the container.
Because servlets are registered that way, they can be mapped to a sub-context of the DispatcherServlet without invoking it.

Configuring the DispatcherServlet yourself is unusual but if you really need to do it, a @Bean of type DispatcherServletPath must be provided as well to provide the path of your custom DispatcherServlet.

4.7. Switch off the Default MVC Configuration

The easiest way to take complete control over MVC configuration is to provide your own @Configuration with the @EnableWebMvc annotation.
Doing so leaves all MVC configuration in your hands.

4.8. Customize ViewResolvers

A ViewResolver is a core component of Spring MVC, translating view names in @Controller to actual View implementations.
Note that ViewResolvers are mainly used in UI applications, rather than REST-style services (a View is not used to render a @ResponseBody).
There are many implementations of ViewResolver to choose from, and Spring on its own is not opinionated about which ones you should use.
Spring Boot, on the other hand, installs one or two for you, depending on what it finds on the classpath and in the application context.
The DispatcherServlet uses all the resolvers it finds in the application context, trying each one in turn until it gets a result.
If you add your own, you have to be aware of the order and in which position your resolver is added.

WebMvcAutoConfiguration adds the following ViewResolvers to your context:

  • An InternalResourceViewResolver named ‘defaultViewResolver’.
    This one locates physical resources that can be rendered by using the DefaultServlet (including static resources and JSP pages, if you use those).
    It applies a prefix and a suffix to the view name and then looks for a physical resource with that path in the servlet context (the defaults are both empty but are accessible for external configuration through spring.mvc.view.prefix and spring.mvc.view.suffix).
    You can override it by providing a bean of the same type.

  • A BeanNameViewResolver named ‘beanNameViewResolver’.
    This is a useful member of the view resolver chain and picks up any beans with the same name as the View being resolved.
    It should not be necessary to override or replace it.

  • A ContentNegotiatingViewResolver named ‘viewResolver’ is added only if there are actually beans of type View present.
    This is a composite resolver, delegating to all the others and attempting to find a match to the ‘Accept’ HTTP header sent by the client.
    There is a useful blog about ContentNegotiatingViewResolver that you might like to study to learn more, and you might also look at the source code for detail.
    You can switch off the auto-configured ContentNegotiatingViewResolver by defining a bean named ‘viewResolver’.

  • If you use Thymeleaf, you also have a ThymeleafViewResolver named ‘thymeleafViewResolver’.
    It looks for resources by surrounding the view name with a prefix and suffix.
    The prefix is spring.thymeleaf.prefix, and the suffix is spring.thymeleaf.suffix.
    The values of the prefix and suffix default to ‘classpath:/templates/’ and ‘.html’, respectively.
    You can override ThymeleafViewResolver by providing a bean of the same name.

  • If you use FreeMarker, you also have a FreeMarkerViewResolver named ‘freeMarkerViewResolver’.
    It looks for resources in a loader path (which is externalized to spring.freemarker.templateLoaderPath and has a default value of ‘classpath:/templates/’) by surrounding the view name with a prefix and a suffix.
    The prefix is externalized to spring.freemarker.prefix, and the suffix is externalized to spring.freemarker.suffix.
    The default values of the prefix and suffix are empty and ‘.ftlh’, respectively.
    You can override FreeMarkerViewResolver by providing a bean of the same name.

  • If you use Groovy templates (actually, if groovy-templates is on your classpath), you also have a GroovyMarkupViewResolver named ‘groovyMarkupViewResolver’.
    It looks for resources in a loader path by surrounding the view name with a prefix and suffix (externalized to spring.groovy.template.prefix and spring.groovy.template.suffix).
    The prefix and suffix have default values of ‘classpath:/templates/’ and ‘.tpl’, respectively.
    You can override GroovyMarkupViewResolver by providing a bean of the same name.

  • If you use Mustache, you also have a MustacheViewResolver named ‘mustacheViewResolver’.
    It looks for resources by surrounding the view name with a prefix and suffix.
    The prefix is spring.mustache.prefix, and the suffix is spring.mustache.suffix.
    The values of the prefix and suffix default to ‘classpath:/templates/’ and ‘.mustache’, respectively.
    You can override MustacheViewResolver by providing a bean of the same name.

For more detail, see the following sections:

  • WebMvcAutoConfiguration

  • ThymeleafAutoConfiguration

  • FreeMarkerAutoConfiguration

  • GroovyTemplateAutoConfiguration

5. Jersey

5.1. Secure Jersey endpoints with Spring Security

Spring Security can be used to secure a Jersey-based web application in much the same way as it can be used to secure a Spring MVC-based web application.
However, if you want to use Spring Security’s method-level security with Jersey, you must configure Jersey to use setStatus(int) rather sendError(int).
This prevents Jersey from committing the response before Spring Security has had an opportunity to report an authentication or authorization failure to the client.

The jersey.config.server.response.setStatusOverSendError property must be set to true on the application’s ResourceConfig bean, as shown in the following example:

import java.util.Collections;

import org.glassfish.jersey.server.ResourceConfig;

import org.springframework.stereotype.Component;

@Component
public class JerseySetStatusOverSendErrorConfig extends ResourceConfig {

    public JerseySetStatusOverSendErrorConfig() {
        register(Endpoint.class);
        setProperties(Collections.singletonMap("jersey.config.server.response.setStatusOverSendError", true));
    }

}

5.2. Use Jersey Alongside Another Web Framework

To use Jersey alongside another web framework, such as Spring MVC, it should be configured so that it will allow the other framework to handle requests that it cannot handle.
First, configure Jersey to use a filter rather than a servlet by configuring the spring.jersey.type application property with a value of filter.
Second, configure your ResourceConfig to forward requests that would have resulted in a 404, as shown in the following example.

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletProperties;

import org.springframework.stereotype.Component;

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(Endpoint.class);
        property(ServletProperties.FILTER_FORWARD_ON_404, true);
    }

}

6. HTTP Clients

Spring Boot offers a number of starters that work with HTTP clients.
This section answers questions related to using them.

6.1. Configure RestTemplate to Use a Proxy

As described in io.html, you can use a RestTemplateCustomizer with RestTemplateBuilder to build a customized RestTemplate.
This is the recommended approach for creating a RestTemplate configured to use a proxy.

The exact details of the proxy configuration depend on the underlying client request factory that is being used.

6.2. Configure the TcpClient used by a Reactor Netty-based WebClient

When Reactor Netty is on the classpath a Reactor Netty-based WebClient is auto-configured.
To customize the client’s handling of network connections, provide a ClientHttpConnector bean.
The following example configures a 60 second connect timeout and adds a ReadTimeoutHandler:

Java

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import reactor.netty.http.client.HttpClient;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.client.reactive.ReactorResourceFactory;

@Configuration(proxyBeanMethods = false)
public class MyReactorNettyClientConfiguration {

    @Bean
    ClientHttpConnector clientHttpConnector(ReactorResourceFactory resourceFactory) {
        HttpClient httpClient = HttpClient.create(resourceFactory.getConnectionProvider())
                .runOn(resourceFactory.getLoopResources())
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 60000)
                .doOnConnected((connection) -> connection.addHandlerLast(new ReadTimeoutHandler(60)));
        return new ReactorClientHttpConnector(httpClient);
    }

}

Kotlin

import io.netty.channel.ChannelOption
import io.netty.handler.timeout.ReadTimeoutHandler
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.client.reactive.ClientHttpConnector
import org.springframework.http.client.reactive.ReactorClientHttpConnector
import org.springframework.http.client.reactive.ReactorResourceFactory
import reactor.netty.http.client.HttpClient

@Configuration(proxyBeanMethods = false)
class MyReactorNettyClientConfiguration {

    @Bean
    fun clientHttpConnector(resourceFactory: ReactorResourceFactory): ClientHttpConnector {
        val httpClient = HttpClient.create(resourceFactory.connectionProvider)
            .runOn(resourceFactory.loopResources)
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 60000)
            .doOnConnected { connection ->
                connection.addHandlerLast(ReadTimeoutHandler(60))
            }
        return ReactorClientHttpConnector(httpClient)
    }

}
Note the use of ReactorResourceFactory for the connection provider and event loop resources.
This ensures efficient sharing of resources for the server receiving requests and the client making requests.

7. Logging

Spring Boot has no mandatory logging dependency, except for the Commons Logging API, which is typically provided by Spring Framework’s spring-jcl module.
To use Logback, you need to include it and spring-jcl on the classpath.
The recommended way to do that is through the starters, which all depend on spring-boot-starter-logging.
For a web application, you need only spring-boot-starter-web, since it depends transitively on the logging starter.
If you use Maven, the following dependency adds logging for you:

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

Spring Boot has a LoggingSystem abstraction that attempts to configure logging based on the content of the classpath.
If Logback is available, it is the first choice.

If the only change you need to make to logging is to set the levels of various loggers, you can do so in application.properties by using the «logging.level» prefix, as shown in the following example:

Properties

logging.level.org.springframework.web=debug
logging.level.org.hibernate=error

Yaml

logging:
  level:
    org.springframework.web: "debug"
    org.hibernate: "error"

You can also set the location of a file to which to write the log (in addition to the console) by using logging.file.name.

To configure the more fine-grained settings of a logging system, you need to use the native configuration format supported by the LoggingSystem in question.
By default, Spring Boot picks up the native configuration from its default location for the system (such as classpath:logback.xml for Logback), but you can set the location of the config file by using the logging.config property.

7.1. Configure Logback for Logging

If you need to apply customizations to logback beyond those that can be achieved with application.properties, you will need to add a standard logback configuration file.
You can add a logback.xml file to the root of your classpath for logback to find.
You can also use logback-spring.xml if you want to use the Spring Boot Logback extensions.

Spring Boot provides a number of logback configurations that can be included in your own configuration.
These includes are designed to allow certain common Spring Boot conventions to be re-applied.

The following files are provided under org/springframework/boot/logging/logback/:

  • defaults.xml — Provides conversion rules, pattern properties and common logger configurations.

  • console-appender.xml — Adds a ConsoleAppender using the CONSOLE_LOG_PATTERN.

  • file-appender.xml — Adds a RollingFileAppender using the FILE_LOG_PATTERN and ROLLING_FILE_NAME_PATTERN with appropriate settings.

In addition, a legacy base.xml file is provided for compatibility with earlier versions of Spring Boot.

A typical custom logback.xml file would look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
    <logger name="org.springframework.web" level="DEBUG"/>
</configuration>

Your logback configuration file can also make use of System properties that the LoggingSystem takes care of creating for you:

  • ${PID}: The current process ID.

  • ${LOG_FILE}: Whether logging.file.name was set in Boot’s external configuration.

  • ${LOG_PATH}: Whether logging.file.path (representing a directory for log files to live in) was set in Boot’s external configuration.

  • ${LOG_EXCEPTION_CONVERSION_WORD}: Whether logging.exception-conversion-word was set in Boot’s external configuration.

  • ${ROLLING_FILE_NAME_PATTERN}: Whether logging.pattern.rolling-file-name was set in Boot’s external configuration.

Spring Boot also provides some nice ANSI color terminal output on a console (but not in a log file) by using a custom Logback converter.
See the CONSOLE_LOG_PATTERN in the defaults.xml configuration for an example.

If Groovy is on the classpath, you should be able to configure Logback with logback.groovy as well.
If present, this setting is given preference.

Spring extensions are not supported with Groovy configuration.
Any logback-spring.groovy files will not be detected.

7.1.1. Configure Logback for File-only Output

If you want to disable console logging and write output only to a file, you need a custom logback-spring.xml that imports file-appender.xml but not console-appender.xml, as shown in the following example:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
    <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
    <root level="INFO">
        <appender-ref ref="FILE" />
    </root>
</configuration>

You also need to add logging.file.name to your application.properties or application.yaml, as shown in the following example:

Properties

logging.file.name=myapplication.log

Yaml

logging:
  file:
    name: "myapplication.log"

7.2. Configure Log4j for Logging

Spring Boot supports Log4j 2 for logging configuration if it is on the classpath.
If you use the starters for assembling dependencies, you have to exclude Logback and then include Log4j 2 instead.
If you do not use the starters, you need to provide (at least) spring-jcl in addition to Log4j 2.

The recommended path is through the starters, even though it requires some jiggling.
The following example shows how to set up the starters in Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Gradle provides a few different ways to set up the starters.
One way is to use a module replacement.
To do so, declare a dependency on the Log4j 2 starter and tell Gradle that any occurrences of the default logging starter should be replaced by the Log4j 2 starter, as shown in the following example:

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-log4j2"
    modules {
        module("org.springframework.boot:spring-boot-starter-logging") {
            replacedBy("org.springframework.boot:spring-boot-starter-log4j2", "Use Log4j2 instead of Logback")
        }
    }
}
The Log4j starters gather together the dependencies for common logging requirements (such as having Tomcat use java.util.logging but configuring the output using Log4j 2).
To ensure that debug logging performed using java.util.logging is routed into Log4j 2, configure its JDK logging adapter by setting the java.util.logging.manager system property to org.apache.logging.log4j.jul.LogManager.

7.2.1. Use YAML or JSON to Configure Log4j 2

In addition to its default XML configuration format, Log4j 2 also supports YAML and JSON configuration files.
To configure Log4j 2 to use an alternative configuration file format, add the appropriate dependencies to the classpath and name your configuration files to match your chosen file format, as shown in the following example:

Format Dependencies File names

YAML

com.fasterxml.jackson.core:jackson-databind + com.fasterxml.jackson.dataformat:jackson-dataformat-yaml

log4j2.yaml + log4j2.yml

JSON

com.fasterxml.jackson.core:jackson-databind

log4j2.json + log4j2.jsn

7.2.2. Use Composite Configuration to Configure Log4j 2

Log4j 2 has support for combining multiple configuration files into a single composite configuration.
To use this support in Spring Boot, configure logging.log4j2.config.override with the locations of one or more secondary configuration files.
The secondary configuration files will be merged with the primary configuration, whether the primary’s source is Spring Boot’s defaults, a standard location such as log4j.xml, or the location configured by the logging.config property.

8. Data Access

Spring Boot includes a number of starters for working with data sources.
This section answers questions related to doing so.

8.1. Configure a Custom DataSource

To configure your own DataSource, define a @Bean of that type in your configuration.
Spring Boot reuses your DataSource anywhere one is required, including database initialization.
If you need to externalize some settings, you can bind your DataSource to the environment (see “features.html”).

The following example shows how to define a data source in a bean:

Java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "app.datasource")
    public SomeDataSource dataSource() {
        return new SomeDataSource();
    }

}

Kotlin

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "app.datasource")
    fun dataSource(): SomeDataSource {
        return SomeDataSource()
    }

}

The following example shows how to define a data source by setting properties:

Properties

app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30

Yaml

app:
  datasource:
    url: "jdbc:h2:mem:mydb"
    username: "sa"
    pool-size: 30

Assuming that SomeDataSource has regular JavaBean properties for the URL, the username, and the pool size, these settings are bound automatically before the DataSource is made available to other components.

Spring Boot also provides a utility builder class, called DataSourceBuilder, that can be used to create one of the standard data sources (if it is on the classpath).
The builder can detect the one to use based on what is available on the classpath.
It also auto-detects the driver based on the JDBC URL.

The following example shows how to create a data source by using a DataSourceBuilder:

Java

import javax.sql.DataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {

    @Bean
    @ConfigurationProperties("app.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

}

Kotlin

import javax.sql.DataSource

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {

    @Bean
    @ConfigurationProperties("app.datasource")
    fun dataSource(): DataSource {
        return DataSourceBuilder.create().build()
    }

}

To run an app with that DataSource, all you need is the connection information.
Pool-specific settings can also be provided.
Check the implementation that is going to be used at runtime for more details.

The following example shows how to define a JDBC data source by setting properties:

Properties

app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30

Yaml

app:
  datasource:
    url: "jdbc:mysql://localhost/test"
    username: "dbuser"
    password: "dbpass"
    pool-size: 30

However, there is a catch.
Because the actual type of the connection pool is not exposed, no keys are generated in the metadata for your custom DataSource and no completion is available in your IDE (because the DataSource interface exposes no properties).
Also, if you happen to have Hikari on the classpath, this basic setup does not work, because Hikari has no url property (but does have a jdbcUrl property).
In that case, you must rewrite your configuration as follows:

Properties

app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30

Yaml

app:
  datasource:
    jdbc-url: "jdbc:mysql://localhost/test"
    username: "dbuser"
    password: "dbpass"
    pool-size: 30

You can fix that by forcing the connection pool to use and return a dedicated implementation rather than DataSource.
You cannot change the implementation at runtime, but the list of options will be explicit.

The following example shows how create a HikariDataSource with DataSourceBuilder:

Java

import com.zaxxer.hikari.HikariDataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {

    @Bean
    @ConfigurationProperties("app.datasource")
    public HikariDataSource dataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

}

Kotlin

import com.zaxxer.hikari.HikariDataSource
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {

    @Bean
    @ConfigurationProperties("app.datasource")
    fun dataSource(): HikariDataSource {
        return DataSourceBuilder.create().type(HikariDataSource::class.java).build()
    }

}

You can even go further by leveraging what DataSourceProperties does for you — that is, by providing a default embedded database with a sensible username and password if no URL is provided.
You can easily initialize a DataSourceBuilder from the state of any DataSourceProperties object, so you could also inject the DataSource that Spring Boot creates automatically.
However, that would split your configuration into two namespaces: url, username, password, type, and driver on spring.datasource and the rest on your custom namespace (app.datasource).
To avoid that, you can redefine a custom DataSourceProperties on your custom namespace, as shown in the following example:

Java

import com.zaxxer.hikari.HikariDataSource;

import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("app.datasource.configuration")
    public HikariDataSource dataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

}

Kotlin

import com.zaxxer.hikari.HikariDataSource
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary

@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource")
    fun dataSourceProperties(): DataSourceProperties {
        return DataSourceProperties()
    }

    @Bean
    @ConfigurationProperties("app.datasource.configuration")
    fun dataSource(properties: DataSourceProperties): HikariDataSource {
        return properties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
    }

}

This setup puts you in sync with what Spring Boot does for you by default, except that a dedicated connection pool is chosen (in code) and its settings are exposed in the app.datasource.configuration sub namespace.
Because DataSourceProperties is taking care of the url/jdbcUrl translation for you, you can configure it as follows:

Properties

app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.configuration.maximum-pool-size=30

Yaml

app:
  datasource:
    url: "jdbc:mysql://localhost/test"
    username: "dbuser"
    password: "dbpass"
    configuration:
      maximum-pool-size: 30
Spring Boot will expose Hikari-specific settings to spring.datasource.hikari.
This example uses a more generic configuration sub namespace as the example does not support multiple datasource implementations.
Because your custom configuration chooses to go with Hikari, app.datasource.type has no effect.
In practice, the builder is initialized with whatever value you might set there and then overridden by the call to .type().

8.2. Configure Two DataSources

If you need to configure multiple data sources, you can apply the same tricks that are described in the previous section.
You must, however, mark one of the DataSource instances as @Primary, because various auto-configurations down the road expect to be able to get one by type.

If you create your own DataSource, the auto-configuration backs off.
In the following example, we provide the exact same feature set as the auto-configuration provides on the primary data source:

Java

import com.zaxxer.hikari.HikariDataSource;
import org.apache.commons.dbcp2.BasicDataSource;

import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration(proxyBeanMethods = false)
public class MyDataSourcesConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first")
    public DataSourceProperties firstDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first.configuration")
    public HikariDataSource firstDataSource(DataSourceProperties firstDataSourceProperties) {
        return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

    @Bean
    @ConfigurationProperties("app.datasource.second")
    public BasicDataSource secondDataSource() {
        return DataSourceBuilder.create().type(BasicDataSource.class).build();
    }

}

Kotlin

import com.zaxxer.hikari.HikariDataSource
import org.apache.commons.dbcp2.BasicDataSource
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary

@Configuration(proxyBeanMethods = false)
class MyDataSourcesConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first")
    fun firstDataSourceProperties(): DataSourceProperties {
        return DataSourceProperties()
    }

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first.configuration")
    fun firstDataSource(firstDataSourceProperties: DataSourceProperties): HikariDataSource {
        return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
    }

    @Bean
    @ConfigurationProperties("app.datasource.second")
    fun secondDataSource(): BasicDataSource {
        return DataSourceBuilder.create().type(BasicDataSource::class.java).build()
    }

}
firstDataSourceProperties has to be flagged as @Primary so that the database initializer feature uses your copy (if you use the initializer).

Both data sources are also bound for advanced customizations.
For instance, you could configure them as follows:

Properties

app.datasource.first.url=jdbc:mysql://localhost/first
app.datasource.first.username=dbuser
app.datasource.first.password=dbpass
app.datasource.first.configuration.maximum-pool-size=30

app.datasource.second.url=jdbc:mysql://localhost/second
app.datasource.second.username=dbuser
app.datasource.second.password=dbpass
app.datasource.second.max-total=30

Yaml

app:
  datasource:
    first:
      url: "jdbc:mysql://localhost/first"
      username: "dbuser"
      password: "dbpass"
      configuration:
        maximum-pool-size: 30

    second:
      url: "jdbc:mysql://localhost/second"
      username: "dbuser"
      password: "dbpass"
      max-total: 30

You can apply the same concept to the secondary DataSource as well, as shown in the following example:

Java

import com.zaxxer.hikari.HikariDataSource;
import org.apache.commons.dbcp2.BasicDataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration(proxyBeanMethods = false)
public class MyCompleteDataSourcesConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first")
    public DataSourceProperties firstDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first.configuration")
    public HikariDataSource firstDataSource(DataSourceProperties firstDataSourceProperties) {
        return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

    @Bean
    @ConfigurationProperties("app.datasource.second")
    public DataSourceProperties secondDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("app.datasource.second.configuration")
    public BasicDataSource secondDataSource(
            @Qualifier("secondDataSourceProperties") DataSourceProperties secondDataSourceProperties) {
        return secondDataSourceProperties.initializeDataSourceBuilder().type(BasicDataSource.class).build();
    }

}

Kotlin

import com.zaxxer.hikari.HikariDataSource
import org.apache.commons.dbcp2.BasicDataSource
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary

@Configuration(proxyBeanMethods = false)
class MyCompleteDataSourcesConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first")
    fun firstDataSourceProperties(): DataSourceProperties {
        return DataSourceProperties()
    }

    @Bean
    @Primary
    @ConfigurationProperties("app.datasource.first.configuration")
    fun firstDataSource(firstDataSourceProperties: DataSourceProperties): HikariDataSource {
        return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
    }

    @Bean
    @ConfigurationProperties("app.datasource.second")
    fun secondDataSourceProperties(): DataSourceProperties {
        return DataSourceProperties()
    }

    @Bean
    @ConfigurationProperties("app.datasource.second.configuration")
    fun secondDataSource(secondDataSourceProperties: DataSourceProperties): BasicDataSource {
        return secondDataSourceProperties.initializeDataSourceBuilder().type(BasicDataSource::class.java).build()
    }

}

The preceding example configures two data sources on custom namespaces with the same logic as Spring Boot would use in auto-configuration.
Note that each configuration sub namespace provides advanced settings based on the chosen implementation.

8.3. Use Spring Data Repositories

Spring Data can create implementations of @Repository interfaces of various flavors.
Spring Boot handles all of that for you, as long as those @Repositories are included in the same package (or a sub-package) of your @EnableAutoConfiguration class.

For many applications, all you need is to put the right Spring Data dependencies on your classpath.
There is a spring-boot-starter-data-jpa for JPA, spring-boot-starter-data-mongodb for Mongodb, and various other starters for supported technologies.
To get started, create some repository interfaces to handle your @Entity objects.

Spring Boot tries to guess the location of your @Repository definitions, based on the @EnableAutoConfiguration it finds.
To get more control, use the @EnableJpaRepositories annotation (from Spring Data JPA).

8.4. Separate @Entity Definitions from Spring Configuration

Spring Boot tries to guess the location of your @Entity definitions, based on the @EnableAutoConfiguration it finds.
To get more control, you can use the @EntityScan annotation, as shown in the following example:

Java

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EntityScan(basePackageClasses = City.class)
public class MyApplication {

    // ...

}

Kotlin

import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EntityScan(basePackageClasses = [City::class])
class MyApplication {

    // ...

}

8.5. Configure JPA Properties

Spring Data JPA already provides some vendor-independent configuration options (such as those for SQL logging), and Spring Boot exposes those options and a few more for Hibernate as external configuration properties.
Some of them are automatically detected according to the context so you should not have to set them.

The spring.jpa.hibernate.ddl-auto is a special case, because, depending on runtime conditions, it has different defaults.
If an embedded database is used and no schema manager (such as Liquibase or Flyway) is handling the DataSource, it defaults to create-drop.
In all other cases, it defaults to none.

The dialect to use is detected by the JPA provider.
If you prefer to set the dialect yourself, set the spring.jpa.database-platform property.

The most common options to set are shown in the following example:

Properties

spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
spring.jpa.show-sql=true

Yaml

spring:
  jpa:
    hibernate:
      naming:
        physical-strategy: "com.example.MyPhysicalNamingStrategy"
    show-sql: true

In addition, all properties in spring.jpa.properties.* are passed through as normal JPA properties (with the prefix stripped) when the local EntityManagerFactory is created.

You need to ensure that names defined under spring.jpa.properties.* exactly match those expected by your JPA provider.
Spring Boot will not attempt any kind of relaxed binding for these entries.

For example, if you want to configure Hibernate’s batch size you must use spring.jpa.properties.hibernate.jdbc.batch_size.
If you use other forms, such as batchSize or batch-size, Hibernate will not apply the setting.

If you need to apply advanced customization to Hibernate properties, consider registering a HibernatePropertiesCustomizer bean that will be invoked prior to creating the EntityManagerFactory.
This takes precedence to anything that is applied by the auto-configuration.

8.6. Configure Hibernate Naming Strategy

Hibernate uses two different naming strategies to map names from the object model to the corresponding database names.
The fully qualified class name of the physical and the implicit strategy implementations can be configured by setting the spring.jpa.hibernate.naming.physical-strategy and spring.jpa.hibernate.naming.implicit-strategy properties, respectively.
Alternatively, if ImplicitNamingStrategy or PhysicalNamingStrategy beans are available in the application context, Hibernate will be automatically configured to use them.

By default, Spring Boot configures the physical naming strategy with CamelCaseToUnderscoresNamingStrategy.
Using this strategy, all dots are replaced by underscores and camel casing is replaced by underscores as well.
Additionally, by default, all table names are generated in lower case.
For example, a TelephoneNumber entity is mapped to the telephone_number table.
If your schema requires mixed-case identifiers, define a custom CamelCaseToUnderscoresNamingStrategy bean, as shown in the following example:

Java

import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

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

@Configuration(proxyBeanMethods = false)
public class MyHibernateConfiguration {

    @Bean
    public CamelCaseToUnderscoresNamingStrategy caseSensitivePhysicalNamingStrategy() {
        return new CamelCaseToUnderscoresNamingStrategy() {

            @Override
            protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
                return false;
            }

        };
    }

}

Kotlin

import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyHibernateConfiguration {

    @Bean
    fun caseSensitivePhysicalNamingStrategy(): CamelCaseToUnderscoresNamingStrategy {
        return object : CamelCaseToUnderscoresNamingStrategy() {
            override fun isCaseInsensitive(jdbcEnvironment: JdbcEnvironment): Boolean {
                return false
            }
        }
    }

}

If you prefer to use Hibernate’s default instead, set the following property:

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

Alternatively, you can configure the following bean:

Java

import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;

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

@Configuration(proxyBeanMethods = false)
class MyHibernateConfiguration {

    @Bean
    PhysicalNamingStrategyStandardImpl caseSensitivePhysicalNamingStrategy() {
        return new PhysicalNamingStrategyStandardImpl();
    }

}

Kotlin

import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
internal class MyHibernateConfiguration {

    @Bean
    fun caseSensitivePhysicalNamingStrategy(): PhysicalNamingStrategyStandardImpl {
        return PhysicalNamingStrategyStandardImpl()
    }

}

8.7. Configure Hibernate Second-Level Caching

Hibernate second-level cache can be configured for a range of cache providers.
Rather than configuring Hibernate to lookup the cache provider again, it is better to provide the one that is available in the context whenever possible.

To do this with JCache, first make sure that org.hibernate.orm:hibernate-jcache is available on the classpath.
Then, add a HibernatePropertiesCustomizer bean as shown in the following example:

Java

import org.hibernate.cache.jcache.ConfigSettings;

import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyHibernateSecondLevelCacheConfiguration {

    @Bean
    public HibernatePropertiesCustomizer hibernateSecondLevelCacheCustomizer(JCacheCacheManager cacheManager) {
        return (properties) -> properties.put(ConfigSettings.CACHE_MANAGER, cacheManager.getCacheManager());
    }

}

Kotlin

import org.hibernate.cache.jcache.ConfigSettings
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer
import org.springframework.cache.jcache.JCacheCacheManager
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyHibernateSecondLevelCacheConfiguration {

    @Bean
    fun hibernateSecondLevelCacheCustomizer(cacheManager: JCacheCacheManager): HibernatePropertiesCustomizer {
        return HibernatePropertiesCustomizer { properties ->
            properties[ConfigSettings.CACHE_MANAGER] = cacheManager.cacheManager
        }
    }

}

This customizer will configure Hibernate to use the same CacheManager as the one that the application uses.
It is also possible to use separate CacheManager instances.
For details, see the Hibernate user guide.

8.8. Use Dependency Injection in Hibernate Components

By default, Spring Boot registers a BeanContainer implementation that uses the BeanFactory so that converters and entity listeners can use regular dependency injection.

You can disable or tune this behavior by registering a HibernatePropertiesCustomizer that removes or changes the hibernate.resource.beans.container property.

8.9. Use a Custom EntityManagerFactory

To take full control of the configuration of the EntityManagerFactory, you need to add a @Bean named ‘entityManagerFactory’.
Spring Boot auto-configuration switches off its entity manager in the presence of a bean of that type.

8.10. Using Multiple EntityManagerFactories

If you need to use JPA against multiple data sources, you likely need one EntityManagerFactory per data source.
The LocalContainerEntityManagerFactoryBean from Spring ORM allows you to configure an EntityManagerFactory for your needs.
You can also reuse JpaProperties to bind settings for each EntityManagerFactory, as shown in the following example:

Java

import javax.sql.DataSource;

import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

@Configuration(proxyBeanMethods = false)
public class MyEntityManagerFactoryConfiguration {

    @Bean
    @ConfigurationProperties("app.jpa.first")
    public JpaProperties firstJpaProperties() {
        return new JpaProperties();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory(DataSource firstDataSource,
            JpaProperties firstJpaProperties) {
        EntityManagerFactoryBuilder builder = createEntityManagerFactoryBuilder(firstJpaProperties);
        return builder.dataSource(firstDataSource).packages(Order.class).persistenceUnit("firstDs").build();
    }

    private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties jpaProperties) {
        JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(jpaProperties);
        return new EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.getProperties(), null);
    }

    private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties) {
        // ... map JPA properties as needed
        return new HibernateJpaVendorAdapter();
    }

}

Kotlin

import javax.sql.DataSource

import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.orm.jpa.JpaVendorAdapter
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter

@Configuration(proxyBeanMethods = false)
class MyEntityManagerFactoryConfiguration {

    @Bean
    @ConfigurationProperties("app.jpa.first")
    fun firstJpaProperties(): JpaProperties {
        return JpaProperties()
    }

    @Bean
    fun firstEntityManagerFactory(
        firstDataSource: DataSource?,
        firstJpaProperties: JpaProperties
    ): LocalContainerEntityManagerFactoryBean {
        val builder = createEntityManagerFactoryBuilder(firstJpaProperties)
        return builder.dataSource(firstDataSource).packages(Order::class.java).persistenceUnit("firstDs").build()
    }

    private fun createEntityManagerFactoryBuilder(jpaProperties: JpaProperties): EntityManagerFactoryBuilder {
        val jpaVendorAdapter = createJpaVendorAdapter(jpaProperties)
        return EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.properties, null)
    }

    private fun createJpaVendorAdapter(jpaProperties: JpaProperties): JpaVendorAdapter {
        // ... map JPA properties as needed
        return HibernateJpaVendorAdapter()
    }

}

The example above creates an EntityManagerFactory using a DataSource bean named firstDataSource.
It scans entities located in the same package as Order.
It is possible to map additional JPA properties using the app.first.jpa namespace.

When you create a bean for LocalContainerEntityManagerFactoryBean yourself, any customization that was applied during the creation of the auto-configured LocalContainerEntityManagerFactoryBean is lost.
For example, in case of Hibernate, any properties under the spring.jpa.hibernate prefix will not be automatically applied to your LocalContainerEntityManagerFactoryBean.
If you were relying on these properties for configuring things like the naming strategy or the DDL mode, you will need to explicitly configure that when creating the LocalContainerEntityManagerFactoryBean bean.

You should provide a similar configuration for any additional data sources for which you need JPA access.
To complete the picture, you need to configure a JpaTransactionManager for each EntityManagerFactory as well.
Alternatively, you might be able to use a JTA transaction manager that spans both.

If you use Spring Data, you need to configure @EnableJpaRepositories accordingly, as shown in the following examples:

Java

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Order.class, entityManagerFactoryRef = "firstEntityManagerFactory")
public class OrderConfiguration {

}

Kotlin

import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.config.EnableJpaRepositories

@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = [Order::class], entityManagerFactoryRef = "firstEntityManagerFactory")
class OrderConfiguration

Java

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Customer.class, entityManagerFactoryRef = "secondEntityManagerFactory")
public class CustomerConfiguration {

}

Kotlin

import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.config.EnableJpaRepositories

@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = [Customer::class], entityManagerFactoryRef = "secondEntityManagerFactory")
class CustomerConfiguration

8.11. Use a Traditional persistence.xml File

Spring Boot will not search for or use a META-INF/persistence.xml by default.
If you prefer to use a traditional persistence.xml, you need to define your own @Bean of type LocalEntityManagerFactoryBean (with an ID of ‘entityManagerFactory’) and set the persistence unit name there.

8.12. Use Spring Data JPA and Mongo Repositories

Spring Data JPA and Spring Data Mongo can both automatically create Repository implementations for you.
If they are both present on the classpath, you might have to do some extra configuration to tell Spring Boot which repositories to create.
The most explicit way to do that is to use the standard Spring Data @EnableJpaRepositories and @EnableMongoRepositories annotations and provide the location of your Repository interfaces.

There are also flags (spring.data.*.repositories.enabled and spring.data.*.repositories.type) that you can use to switch the auto-configured repositories on and off in external configuration.
Doing so is useful, for instance, in case you want to switch off the Mongo repositories and still use the auto-configured MongoTemplate.

The same obstacle and the same features exist for other auto-configured Spring Data repository types (Elasticsearch, Redis, and others).
To work with them, change the names of the annotations and flags accordingly.

8.13. Customize Spring Data’s Web Support

Spring Data provides web support that simplifies the use of Spring Data repositories in a web application.
Spring Boot provides properties in the spring.data.web namespace for customizing its configuration.
Note that if you are using Spring Data REST, you must use the properties in the spring.data.rest namespace instead.

8.14. Expose Spring Data Repositories as REST Endpoint

Spring Data REST can expose the Repository implementations as REST endpoints for you,
provided Spring MVC has been enabled for the application.

Spring Boot exposes a set of useful properties (from the spring.data.rest namespace) that customize the RepositoryRestConfiguration.
If you need to provide additional customization, you should use a RepositoryRestConfigurer bean.

If you do not specify any order on your custom RepositoryRestConfigurer, it runs after the one Spring Boot uses internally.
If you need to specify an order, make sure it is higher than 0.

8.15. Configure a Component that is Used by JPA

If you want to configure a component that JPA uses, then you need to ensure that the component is initialized before JPA.
When the component is auto-configured, Spring Boot takes care of this for you.
For example, when Flyway is auto-configured, Hibernate is configured to depend upon Flyway so that Flyway has a chance to initialize the database before Hibernate tries to use it.

If you are configuring a component yourself, you can use an EntityManagerFactoryDependsOnPostProcessor subclass as a convenient way of setting up the necessary dependencies.
For example, if you use Hibernate Search with Elasticsearch as its index manager, any EntityManagerFactory beans must be configured to depend on the elasticsearchClient bean, as shown in the following example:

Java

import jakarta.persistence.EntityManagerFactory;

import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor;
import org.springframework.stereotype.Component;

/**
 * {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that
 * {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean.
 */
@Component
public class ElasticsearchEntityManagerFactoryDependsOnPostProcessor
        extends EntityManagerFactoryDependsOnPostProcessor {

    public ElasticsearchEntityManagerFactoryDependsOnPostProcessor() {
        super("elasticsearchClient");
    }

}

Kotlin

import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor
import org.springframework.stereotype.Component

@Component
class ElasticsearchEntityManagerFactoryDependsOnPostProcessor :
    EntityManagerFactoryDependsOnPostProcessor("elasticsearchClient")

8.16. Configure jOOQ with Two DataSources

If you need to use jOOQ with multiple data sources, you should create your own DSLContext for each one.
See JooqAutoConfiguration for more details.

In particular, JooqExceptionTranslator and SpringTransactionProvider can be reused to provide similar features to what the auto-configuration does with a single DataSource.

9. Database Initialization

An SQL database can be initialized in different ways depending on what your stack is.
Of course, you can also do it manually, provided the database is a separate process.
It is recommended to use a single mechanism for schema generation.

9.1. Initialize a Database Using JPA

JPA has features for DDL generation, and these can be set up to run on startup against the database.
This is controlled through two external properties:

  • spring.jpa.generate-ddl (boolean) switches the feature on and off and is vendor independent.

  • spring.jpa.hibernate.ddl-auto (enum) is a Hibernate feature that controls the behavior in a more fine-grained way.
    This feature is described in more detail later in this guide.

9.2. Initialize a Database Using Hibernate

You can set spring.jpa.hibernate.ddl-auto explicitly and the standard Hibernate property values are none, validate, update, create, and create-drop.
Spring Boot chooses a default value for you based on whether it thinks your database is embedded.
It defaults to create-drop if no schema manager has been detected or none in all other cases.
An embedded database is detected by looking at the Connection type and JDBC url.
hsqldb, h2, and derby are candidates, and others are not.
Be careful when switching from in-memory to a ‘real’ database that you do not make assumptions about the existence of the tables and data in the new platform.
You either have to set ddl-auto explicitly or use one of the other mechanisms to initialize the database.

You can output the schema creation by enabling the org.hibernate.SQL logger.
This is done for you automatically if you enable the debug mode.

In addition, a file named import.sql in the root of the classpath is executed on startup if Hibernate creates the schema from scratch (that is, if the ddl-auto property is set to create or create-drop).
This can be useful for demos and for testing if you are careful but is probably not something you want to be on the classpath in production.
It is a Hibernate feature (and has nothing to do with Spring).

9.3. Initialize a Database Using Basic SQL Scripts

Spring Boot can automatically create the schema (DDL scripts) of your JDBC DataSource or R2DBC ConnectionFactory and initialize it (DML scripts).
It loads SQL from the standard root classpath locations: schema.sql and data.sql, respectively.
In addition, Spring Boot processes the schema-${platform}.sql and data-${platform}.sql files (if present), where platform is the value of spring.sql.init.platform.
This allows you to switch to database-specific scripts if necessary.
For example, you might choose to set it to the vendor name of the database (hsqldb, h2, oracle, mysql, postgresql, and so on).
By default, SQL database initialization is only performed when using an embedded in-memory database.
To always initialize an SQL database, irrespective of its type, set spring.sql.init.mode to always.
Similarly, to disable initialization, set spring.sql.init.mode to never.
By default, Spring Boot enables the fail-fast feature of its script-based database initializer.
This means that, if the scripts cause exceptions, the application fails to start.
You can tune that behavior by setting spring.sql.init.continue-on-error.

Script-based DataSource initialization is performed, by default, before any JPA EntityManagerFactory beans are created.
schema.sql can be used to create the schema for JPA-managed entities and data.sql can be used to populate it.
While we do not recommend using multiple data source initialization technologies, if you want script-based DataSource initialization to be able to build upon the schema creation performed by Hibernate, set spring.jpa.defer-datasource-initialization to true.
This will defer data source initialization until after any EntityManagerFactory beans have been created and initialized.
schema.sql can then be used to make additions to any schema creation performed by Hibernate and data.sql can be used to populate it.

If you are using a Higher-level Database Migration Tool, like Flyway or Liquibase, you should use them alone to create and initialize the schema.
Using the basic schema.sql and data.sql scripts alongside Flyway or Liquibase is not recommended and support will be removed in a future release.

9.4. Initialize a Spring Batch Database

If you use Spring Batch, it comes pre-packaged with SQL initialization scripts for most popular database platforms.
Spring Boot can detect your database type and execute those scripts on startup.
If you use an embedded database, this happens by default.
You can also enable it for any database type, as shown in the following example:

Properties

spring.batch.jdbc.initialize-schema=always

Yaml

spring:
  batch:
    jdbc:
      initialize-schema: "always"

You can also switch off the initialization explicitly by setting spring.batch.jdbc.initialize-schema to never.

9.5. Use a Higher-level Database Migration Tool

Spring Boot supports two higher-level migration tools: Flyway and Liquibase.

9.5.1. Execute Flyway Database Migrations on Startup

To automatically run Flyway database migrations on startup, add the org.flywaydb:flyway-core to your classpath.

Typically, migrations are scripts in the form V<VERSION>__<NAME>.sql (with <VERSION> an underscore-separated version, such as ‘1’ or ‘2_1’).
By default, they are in a directory called classpath:db/migration, but you can modify that location by setting spring.flyway.locations.
This is a comma-separated list of one or more classpath: or filesystem: locations.
For example, the following configuration would search for scripts in both the default classpath location and the /opt/migration directory:

Properties

spring.flyway.locations=classpath:db/migration,filesystem:/opt/migration

Yaml

spring:
  flyway:
    locations: "classpath:db/migration,filesystem:/opt/migration"

You can also add a special {vendor} placeholder to use vendor-specific scripts.
Assume the following:

Properties

spring.flyway.locations=classpath:db/migration/{vendor}

Yaml

spring:
  flyway:
    locations: "classpath:db/migration/{vendor}"

Rather than using db/migration, the preceding configuration sets the directory to use according to the type of the database (such as db/migration/mysql for MySQL).
The list of supported databases is available in DatabaseDriver.

Migrations can also be written in Java.
Flyway will be auto-configured with any beans that implement JavaMigration.

FlywayProperties provides most of Flyway’s settings and a small set of additional properties that can be used to disable the migrations or switch off the location checking.
If you need more control over the configuration, consider registering a FlywayConfigurationCustomizer bean.

Spring Boot calls Flyway.migrate() to perform the database migration.
If you would like more control, provide a @Bean that implements FlywayMigrationStrategy.

Flyway supports SQL and Java callbacks.
To use SQL-based callbacks, place the callback scripts in the classpath:db/migration directory.
To use Java-based callbacks, create one or more beans that implement Callback.
Any such beans are automatically registered with Flyway.
They can be ordered by using @Order or by implementing Ordered.
Beans that implement the deprecated FlywayCallback interface can also be detected, however they cannot be used alongside Callback beans.

By default, Flyway autowires the (@Primary) DataSource in your context and uses that for migrations.
If you like to use a different DataSource, you can create one and mark its @Bean as @FlywayDataSource.
If you do so and want two data sources, remember to create another one and mark it as @Primary.
Alternatively, you can use Flyway’s native DataSource by setting spring.flyway.[url,user,password] in external properties.
Setting either spring.flyway.url or spring.flyway.user is sufficient to cause Flyway to use its own DataSource.
If any of the three properties has not been set, the value of its equivalent spring.datasource property will be used.

You can also use Flyway to provide data for specific scenarios.
For example, you can place test-specific migrations in src/test/resources and they are run only when your application starts for testing.
Also, you can use profile-specific configuration to customize spring.flyway.locations so that certain migrations run only when a particular profile is active.
For example, in application-dev.properties, you might specify the following setting:

Properties

spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration

Yaml

spring:
  flyway:
    locations: "classpath:/db/migration,classpath:/dev/db/migration"

With that setup, migrations in dev/db/migration run only when the dev profile is active.

9.5.2. Execute Liquibase Database Migrations on Startup

To automatically run Liquibase database migrations on startup, add the org.liquibase:liquibase-core to your classpath.

When you add the org.liquibase:liquibase-core to your classpath, database migrations run by default for both during application startup and before your tests run.
This behavior can be customized by using the spring.liquibase.enabled property, setting different values in the main and test configurations.
It is not possible to use two different ways to initialize the database (for example Liquibase for application startup, JPA for test runs).

By default, the master change log is read from db/changelog/db.changelog-master.yaml, but you can change the location by setting spring.liquibase.change-log.
In addition to YAML, Liquibase also supports JSON, XML, and SQL change log formats.

By default, Liquibase autowires the (@Primary) DataSource in your context and uses that for migrations.
If you need to use a different DataSource, you can create one and mark its @Bean as @LiquibaseDataSource.
If you do so and you want two data sources, remember to create another one and mark it as @Primary.
Alternatively, you can use Liquibase’s native DataSource by setting spring.liquibase.[driver-class-name,url,user,password] in external properties.
Setting either spring.liquibase.url or spring.liquibase.user is sufficient to cause Liquibase to use its own DataSource.
If any of the three properties has not been set, the value of its equivalent spring.datasource property will be used.

See LiquibaseProperties for details about available settings such as contexts, the default schema, and others.

9.6. Depend Upon an Initialized Database

Database initialization is performed while the application is starting up as part of application context refresh.
To allow an initialized database to be accessed during startup, beans that act as database initializers and beans that require that database to have been initialized are detected automatically.
Beans whose initialization depends upon the database having been initialized are configured to depend upon those that initialize it.
If, during startup, your application tries to access the database and it has not been initialized, you can configure additional detection of beans that initialize the database and require the database to have been initialized.

9.6.1. Detect a Database Initializer

Spring Boot will automatically detect beans of the following types that initialize an SQL database:

  • DataSourceScriptDatabaseInitializer

  • EntityManagerFactory

  • Flyway

  • FlywayMigrationInitializer

  • R2dbcScriptDatabaseInitializer

  • SpringLiquibase

If you are using a third-party starter for a database initialization library, it may provide a detector such that beans of other types are also detected automatically.
To have other beans be detected, register an implementation of DatabaseInitializerDetector in META-INF/spring.factories.

9.6.2. Detect a Bean That Depends On Database Initialization

Spring Boot will automatically detect beans of the following types that depends upon database initialization:

  • AbstractEntityManagerFactoryBean (unless spring.jpa.defer-datasource-initialization is set to true)

  • DSLContext (jOOQ)

  • EntityManagerFactory (unless spring.jpa.defer-datasource-initialization is set to true)

  • JdbcOperations

  • NamedParameterJdbcOperations

If you are using a third-party starter data access library, it may provide a detector such that beans of other types are also detected automatically.
To have other beans be detected, register an implementation of DependsOnDatabaseInitializationDetector in META-INF/spring.factories.
Alternatively, annotate the bean’s class or its @Bean method with @DependsOnDatabaseInitialization.

10. Messaging

Spring Boot offers a number of starters to support messaging.
This section answers questions that arise from using messaging with Spring Boot.

10.1. Disable Transacted JMS Session

If your JMS broker does not support transacted sessions, you have to disable the support of transactions altogether.
If you create your own JmsListenerContainerFactory, there is nothing to do, since, by default it cannot be transacted.
If you want to use the DefaultJmsListenerContainerFactoryConfigurer to reuse Spring Boot’s default, you can disable transacted sessions, as follows:

Java

import jakarta.jms.ConnectionFactory;

import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;

@Configuration(proxyBeanMethods = false)
public class MyJmsConfiguration {

    @Bean
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory,
            DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory listenerFactory = new DefaultJmsListenerContainerFactory();
        configurer.configure(listenerFactory, connectionFactory);
        listenerFactory.setTransactionManager(null);
        listenerFactory.setSessionTransacted(false);
        return listenerFactory;
    }

}

Kotlin

import jakarta.jms.ConnectionFactory
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.jms.config.DefaultJmsListenerContainerFactory

@Configuration(proxyBeanMethods = false)
class MyJmsConfiguration {

    @Bean
    fun jmsListenerContainerFactory(connectionFactory: ConnectionFactory?,
            configurer: DefaultJmsListenerContainerFactoryConfigurer): DefaultJmsListenerContainerFactory {
        val listenerFactory = DefaultJmsListenerContainerFactory()
        configurer.configure(listenerFactory, connectionFactory)
        listenerFactory.setTransactionManager(null)
        listenerFactory.setSessionTransacted(false)
        return listenerFactory
    }

}

The preceding example overrides the default factory, and it should be applied to any other factory that your application defines, if any.

11. Batch Applications

A number of questions often arise when people use Spring Batch from within a Spring Boot application.
This section addresses those questions.

11.1. Specifying a Batch Data Source

By default, batch applications require a DataSource to store job details.
Spring Batch expects a single DataSource by default.
To have it use a DataSource other than the application’s main DataSource, declare a DataSource bean, annotating its @Bean method with @BatchDataSource.
If you do so and want two data sources, remember to mark the other one @Primary.
To take greater control, implement BatchConfigurer.
See The Javadoc of @EnableBatchProcessing for more details.

11.2. Running Spring Batch Jobs on Startup

Spring Batch auto-configuration is enabled by adding @EnableBatchProcessing to one of your @Configuration classes.

If a single Job is found in the application context, it is executed on startup (see JobLauncherApplicationRunner for details).
If multiple Job beans are found, the job that should be executed must be specified using spring.batch.job.name.

To disable running a Job found in the application content, set the spring.batch.job.enabled to false.

11.3. Running From the Command Line

Spring Boot converts any command line argument starting with -- to a property to add to the Environment, see accessing command line properties.
This should not be used to pass arguments to batch jobs.
To specify batch arguments on the command line, use the regular format (that is without --), as shown in the following example:

$ java -jar myapp.jar someParameter=someValue anotherParameter=anotherValue

If you specify a property of the Environment on the command line, it is ignored by the job.
Consider the following command:

$ java -jar myapp.jar --server.port=7070 someParameter=someValue

This provides only one argument to the batch job: someParameter=someValue.

11.4. Storing the Job Repository

Spring Batch requires a data store for the Job repository.
If you use Spring Boot, you must use an actual database.
Note that it can be an in-memory database, see Configuring a Job Repository.

12. Actuator

Spring Boot includes the Spring Boot Actuator.
This section answers questions that often arise from its use.

12.1. Change the HTTP Port or Address of the Actuator Endpoints

In a standalone application, the Actuator HTTP port defaults to the same as the main HTTP port.
To make the application listen on a different port, set the external property: management.server.port.
To listen on a completely different network address (such as when you have an internal network for management and an external one for user applications), you can also set management.server.address to a valid IP address to which the server is able to bind.

12.2. Customize the ‘whitelabel’ Error Page

Spring Boot installs a ‘whitelabel’ error page that you see in a browser client if you encounter a server error (machine clients consuming JSON and other media types should see a sensible response with the right error code).

Set server.error.whitelabel.enabled=false to switch the default error page off.
Doing so restores the default of the servlet container that you are using.
Note that Spring Boot still tries to resolve the error view, so you should probably add your own error page rather than disabling it completely.

Overriding the error page with your own depends on the templating technology that you use.
For example, if you use Thymeleaf, you can add an error.html template.
If you use FreeMarker, you can add an error.ftlh template.
In general, you need a View that resolves with a name of error or a @Controller that handles the /error path.
Unless you replaced some of the default configuration, you should find a BeanNameViewResolver in your ApplicationContext, so a @Bean named error would be one way of doing that.
See ErrorMvcAutoConfiguration for more options.

See also the section on “Error Handling” for details of how to register handlers in the servlet container.

12.3. Sanitize Sensitive Values

Information returned by the /env, /configprops and /quartz endpoints can be somewhat sensitive.
All values are sanitized by default (that is replaced by ******).
Viewing original values in the unsanitized form can be configured per endpoint using the showValues property for that endpoint.
This property can be configured to have the following values:

  • ALWAYS — all values are shown in their unsanitized form to all users

  • NEVER — all values are always sanitized (that is replaced by ******)

  • WHEN_AUTHORIZED — all values are shown in their unsanitized form to authorized users

For HTTP endpoints, a user is considered to be authorized if they have authenticated and have the roles configured by the endpoint’s roles property.
By default, any authenticated user is authorized.
For JMX endpoints, all users are always authorized.

Properties

management.endpoint.env.show-values=WHEN_AUTHORIZED
management.endpoint.env.roles=admin

Yaml

management:
  endpoint:
    env:
      show-values: WHEN_AUTHORIZED
      roles: "admin"

The configuration above enables the ability for all users with the admin role to view all values in their original form from the /env endpoint.

When show-values is set to ALWAYS or WHEN_AUTHORIZED any sanitization applied by a SanitizingFunction will still be applied.

12.3.1. Customizing Sanitization

Sanitization can be customized in two different ways.

To take more control over the sanitization, define a SanitizingFunction bean.
The SanitizableData with which the function is called provides access to the key and value as well as the PropertySource from which they came.
This allows you to, for example, sanitize every value that comes from a particular property source.
Each SanitizingFunction is called in order until a function changes the value of the sanitizable data.
If no function changes its value, the built-in key-based sanitization is performed.

12.4. Map Health Indicators to Micrometer Metrics

Spring Boot health indicators return a Status type to indicate the overall system health.
If you want to monitor or alert on levels of health for a particular application, you can export these statuses as metrics with Micrometer.
By default, the status codes “UP”, “DOWN”, “OUT_OF_SERVICE” and “UNKNOWN” are used by Spring Boot.
To export these, you will need to convert these states to some set of numbers so that they can be used with a Micrometer Gauge.

The following example shows one way to write such an exporter:

Java

import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;

import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.health.Status;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyHealthMetricsExportConfiguration {

    public MyHealthMetricsExportConfiguration(MeterRegistry registry, HealthEndpoint healthEndpoint) {
        // This example presumes common tags (such as the app) are applied elsewhere
        Gauge.builder("health", healthEndpoint, this::getStatusCode).strongReference(true).register(registry);
    }

    private int getStatusCode(HealthEndpoint health) {
        Status status = health.health().getStatus();
        if (Status.UP.equals(status)) {
            return 3;
        }
        if (Status.OUT_OF_SERVICE.equals(status)) {
            return 2;
        }
        if (Status.DOWN.equals(status)) {
            return 1;
        }
        return 0;
    }

}

Kotlin

import io.micrometer.core.instrument.Gauge
import io.micrometer.core.instrument.MeterRegistry
import org.springframework.boot.actuate.health.HealthEndpoint
import org.springframework.boot.actuate.health.Status
import org.springframework.context.annotation.Configuration

@Configuration(proxyBeanMethods = false)
class MyHealthMetricsExportConfiguration(registry: MeterRegistry, healthEndpoint: HealthEndpoint) {

    init {
        // This example presumes common tags (such as the app) are applied elsewhere
        Gauge.builder("health", healthEndpoint) { health ->
            getStatusCode(health).toDouble()
        }.strongReference(true).register(registry)
    }

    private fun getStatusCode(health: HealthEndpoint): Int {
        val status = health.health().status
        if (Status.UP == status) {
            return 3
        }
        if (Status.OUT_OF_SERVICE == status) {
            return 2
        }
        if (Status.DOWN == status) {
            return 1
        }
        return 0
    }

}

13. Security

This section addresses questions about security when working with Spring Boot, including questions that arise from using Spring Security with Spring Boot.

13.1. Switch off the Spring Boot Security Configuration

If you define a @Configuration with a SecurityFilterChain bean in your application, it switches off the default webapp security settings in Spring Boot.

13.2. Change the UserDetailsService and Add User Accounts

If you provide a @Bean of type AuthenticationManager, AuthenticationProvider, or UserDetailsService, the default @Bean for InMemoryUserDetailsManager is not created.
This means you have the full feature set of Spring Security available (such as various authentication options).

The easiest way to add user accounts is to provide your own UserDetailsService bean.

13.3. Enable HTTPS When Running behind a Proxy Server

Ensuring that all your main endpoints are only available over HTTPS is an important chore for any application.
If you use Tomcat as a servlet container, then Spring Boot adds Tomcat’s own RemoteIpValve automatically if it detects some environment settings, and you should be able to rely on the HttpServletRequest to report whether it is secure or not (even downstream of a proxy server that handles the real SSL termination).
The standard behavior is determined by the presence or absence of certain request headers (x-forwarded-for and x-forwarded-proto), whose names are conventional, so it should work with most front-end proxies.
You can switch on the valve by adding some entries to application.properties, as shown in the following example:

Properties

server.tomcat.remoteip.remote-ip-header=x-forwarded-for
server.tomcat.remoteip.protocol-header=x-forwarded-proto

Yaml

server:
  tomcat:
    remoteip:
      remote-ip-header: "x-forwarded-for"
      protocol-header: "x-forwarded-proto"

(The presence of either of those properties switches on the valve.
Alternatively, you can add the RemoteIpValve by customizing the TomcatServletWebServerFactory using a WebServerFactoryCustomizer bean.)

To configure Spring Security to require a secure channel for all (or some) requests, consider adding your own SecurityFilterChain bean that adds the following HttpSecurity configuration:

Java

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.web.SecurityFilterChain;

@Configuration
public class MySecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // Customize the application security ...
        http.requiresChannel((channel) -> channel.anyRequest().requiresSecure());
        return http.build();
    }

}

Kotlin

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.web.SecurityFilterChain

@Configuration
class MySecurityConfig {

    @Bean
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
        // Customize the application security ...
        http.requiresChannel().anyRequest().requiresSecure()
        return http.build()
    }

}

14. Hot Swapping

Spring Boot supports hot swapping.
This section answers questions about how it works.

14.1. Reload Static Content

There are several options for hot reloading.
The recommended approach is to use spring-boot-devtools, as it provides additional development-time features, such as support for fast application restarts and LiveReload as well as sensible development-time configuration (such as template caching).
Devtools works by monitoring the classpath for changes.
This means that static resource changes must be «built» for the change to take effect.
By default, this happens automatically in Eclipse when you save your changes.
In IntelliJ IDEA, the Make Project command triggers the necessary build.
Due to the default restart exclusions, changes to static resources do not trigger a restart of your application.
They do, however, trigger a live reload.

Alternatively, running in an IDE (especially with debugging on) is a good way to do development (all modern IDEs allow reloading of static resources and usually also allow hot-swapping of Java class changes).

Finally, the Maven and Gradle plugins can be configured (see the addResources property) to support running from the command line with reloading of static files directly from source.
You can use that with an external css/js compiler process if you are writing that code with higher-level tools.

14.2. Reload Templates without Restarting the Container

Most of the templating technologies supported by Spring Boot include a configuration option to disable caching (described later in this document).
If you use the spring-boot-devtools module, these properties are automatically configured for you at development time.

14.2.1. Thymeleaf Templates

If you use Thymeleaf, set spring.thymeleaf.cache to false.
See ThymeleafAutoConfiguration for other Thymeleaf customization options.

14.2.2. FreeMarker Templates

If you use FreeMarker, set spring.freemarker.cache to false.
See FreeMarkerAutoConfiguration for other FreeMarker customization options.

14.2.3. Groovy Templates

If you use Groovy templates, set spring.groovy.template.cache to false.
See GroovyTemplateAutoConfiguration for other Groovy customization options.

14.3. Fast Application Restarts

The spring-boot-devtools module includes support for automatic application restarts.
While not as fast as technologies such as JRebel it is usually significantly faster than a “cold start”.
You should probably give it a try before investigating some of the more complex reload options discussed later in this document.

For more details, see the using.html section.

14.4. Reload Java Classes without Restarting the Container

Many modern IDEs (Eclipse, IDEA, and others) support hot swapping of bytecode.
Consequently, if you make a change that does not affect class or method signatures, it should reload cleanly with no side effects.

15. Testing

Spring Boot includes a number of testing utilities and support classes as well as a dedicated starter that provides common test dependencies.
This section answers common questions about testing.

15.1. Testing With Spring Security

Spring Security provides support for running tests as a specific user.
For example, the test in the snippet below will run with an authenticated user that has the ADMIN role.

Java

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

@WebMvcTest(UserController.class)
class MySecurityTests {

    @Autowired
    private MockMvc mvc;

    @Test
    @WithMockUser(roles = "ADMIN")
    void requestProtectedUrlWithUser() throws Exception {
        this.mvc.perform(get("/"));
    }

}

Kotlin

import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.security.test.context.support.WithMockUser
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders

@WebMvcTest(UserController::class)
class MySecurityTests(@Autowired val mvc: MockMvc) {

    @Test
    @WithMockUser(roles = ["ADMIN"])
    fun requestProtectedUrlWithUser() {
        mvc.perform(MockMvcRequestBuilders.get("/"))
    }

}

Spring Security provides comprehensive integration with Spring MVC Test and this can also be used when testing controllers using the @WebMvcTest slice and MockMvc.

For additional details on Spring Security’s testing support, see Spring Security’s reference documentation.

15.2. Use Testcontainers for Integration Testing

The Testcontainers library provides a way to manage services running inside Docker containers.
It integrates with JUnit, allowing you to write a test class that can start up a container before any of the tests run.
Testcontainers is especially useful for writing integration tests that talk to a real backend service such as MySQL, MongoDB, Cassandra and others.
Testcontainers can be used in a Spring Boot test as follows:

Java

import org.junit.jupiter.api.Test;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
@Testcontainers
class MyIntegrationTests {

    @Container
    static Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.2");

    @Test
    void myTest() {
        // ...
    }

}

Kotlin

import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
import org.testcontainers.containers.Neo4jContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers

@SpringBootTest
@Testcontainers
internal class MyIntegrationTests {

    @Test
    fun myTest() {
        // ...
    }

    companion object {
        @Container
        var neo4j: Neo4jContainer<*> = Neo4jContainer<Nothing>("neo4j:4.2")
    }

}

This will start up a docker container running Neo4j (if Docker is running locally) before any of the tests are run.
In most cases, you will need to configure the application using details from the running container, such as container IP or port.

This can be done with a static @DynamicPropertySource method that allows adding dynamic property values to the Spring Environment.

Java

import org.junit.jupiter.api.Test;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;

@SpringBootTest
@Testcontainers
class MyIntegrationTests {

    @Container
    static Neo4jContainer<?> neo4j = new Neo4jContainer<>("neo4j:4.2");

    @Test
    void myTest() {
        // ...
    }

    @DynamicPropertySource
    static void neo4jProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.neo4j.uri", neo4j::getBoltUrl);
    }

}

Kotlin

import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.DynamicPropertyRegistry
import org.springframework.test.context.DynamicPropertySource
import org.testcontainers.containers.Neo4jContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers

@SpringBootTest
@Testcontainers
internal class MyIntegrationTests {

    @Test
    fun myTest() {
        // ...
    }

    companion object {

        @Container
        var neo4j: Neo4jContainer<*> = Neo4jContainer<Nothing>("neo4j:4.2")

        @DynamicPropertySource
        fun neo4jProperties(registry: DynamicPropertyRegistry) {
            registry.add("spring.neo4j.uri") { neo4j.boltUrl }
        }

    }

}

The above configuration allows Neo4j-related beans in the application to communicate with Neo4j running inside the Testcontainers-managed Docker container.

15.3. Structure @Configuration classes for inclusion in slice tests

Slice tests work by restricting Spring Framework’s component scanning to a limited set of components based on their type.
For any beans that are not created through component scanning, for example, beans that are created using the @Bean annotation, slice tests will not be able to include/exclude them from the application context.
Consider this example:

import org.apache.commons.dbcp2.BasicDataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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.web.SecurityFilterChain;

@Configuration(proxyBeanMethods = false)
public class MyConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
        return http.build();
    }

    @Bean
    @ConfigurationProperties("app.datasource.second")
    public BasicDataSource secondDataSource() {
        return DataSourceBuilder.create().type(BasicDataSource.class).build();
    }

}

For a @WebMvcTest for an application with the above @Configuration class, you might expect to have the SecurityFilterChain bean in the application context so that you can test if your controller endpoints are secured properly.
However, MyConfiguration is not picked up by @WebMvcTest’s component scanning filter because it doesn’t match any of the types specified by the filter.
You can include the configuration explicitly by annotating the test class with @Import(MyConfiguration.class).
This will load all the beans in MyConfiguration including the BasicDataSource bean which isn’t required when testing the web tier.
Splitting the configuration class into two will enable importing just the 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.web.SecurityFilterChain;

@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
        return http.build();
    }

}
import org.apache.commons.dbcp2.BasicDataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyDatasourceConfiguration {

    @Bean
    @ConfigurationProperties("app.datasource.second")
    public BasicDataSource secondDataSource() {
        return DataSourceBuilder.create().type(BasicDataSource.class).build();
    }

}

Having a single configuration class can be inefficient when beans of a certain domain need to be included in slice tests.
Instead, structuring the application’s configuration as multiple granular classes with beans for a specific domain can enable importing them only for specific slice tests.

16. Build

Spring Boot includes build plugins for Maven and Gradle.
This section answers common questions about these plugins.

16.1. Generate Build Information

Both the Maven plugin and the Gradle plugin allow generating build information containing the coordinates, name, and version of the project.
The plugins can also be configured to add additional properties through configuration.
When such a file is present, Spring Boot auto-configures a BuildProperties bean.

To generate build information with Maven, add an execution for the build-info goal, as shown in the following example:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>3.0.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>build-info</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

The following example does the same with Gradle:

springBoot {
    buildInfo()
}

16.2. Generate Git Information

Both Maven and Gradle allow generating a git.properties file containing information about the state of your git source code repository when the project was built.

For Maven users, the spring-boot-starter-parent POM includes a pre-configured plugin to generate a git.properties file.
To use it, add the following declaration for the Git Commit Id Plugin to your POM:

<build>
    <plugins>
        <plugin>
            <groupId>io.github.git-commit-id</groupId>
            <artifactId>git-commit-id-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Gradle users can achieve the same result by using the gradle-git-properties plugin, as shown in the following example:

plugins {
    id "com.gorylenko.gradle-git-properties" version "2.4.1"
}

Both the Maven and Gradle plugins allow the properties that are included in git.properties to be configured.

The commit time in git.properties is expected to match the following format: yyyy-MM-dd’T’HH:mm:ssZ.
This is the default format for both plugins listed above.
Using this format lets the time be parsed into a Date and its format, when serialized to JSON, to be controlled by Jackson’s date serialization configuration settings.

16.3. Customize Dependency Versions

The spring-boot-dependencies POM manages the versions of common dependencies.
The Spring Boot plugins for Maven and Gradle allow these managed dependency versions to be customized using build properties.

Each Spring Boot release is designed and tested against this specific set of third-party dependencies.
Overriding versions may cause compatibility issues.

To override dependency versions with Maven, see this section of the Maven plugin’s documentation.

To override dependency versions in Gradle, see this section of the Gradle plugin’s documentation.

16.4. Create an Executable JAR with Maven

The spring-boot-maven-plugin can be used to create an executable “fat” JAR.
If you use the spring-boot-starter-parent POM, you can declare the plugin and your jars are repackaged as follows:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

If you do not use the parent POM, you can still use the plugin.
However, you must additionally add an <executions> section, as follows:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>3.0.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

16.5. Use a Spring Boot Application as a Dependency

Like a war file, a Spring Boot application is not intended to be used as a dependency.
If your application contains classes that you want to share with other projects, the recommended approach is to move that code into a separate module.
The separate module can then be depended upon by your application and other projects.

If you cannot rearrange your code as recommended above, Spring Boot’s Maven and Gradle plugins must be configured to produce a separate artifact that is suitable for use as a dependency.
The executable archive cannot be used as a dependency as the executable jar format packages application classes in BOOT-INF/classes.
This means that they cannot be found when the executable jar is used as a dependency.

To produce the two artifacts, one that can be used as a dependency and one that is executable, a classifier must be specified.
This classifier is applied to the name of the executable archive, leaving the default archive for use as a dependency.

To configure a classifier of exec in Maven, you can use the following configuration:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <classifier>exec</classifier>
            </configuration>
        </plugin>
    </plugins>
</build>

Most nested libraries in an executable jar do not need to be unpacked in order to run.
However, certain libraries can have problems.
For example, JRuby includes its own nested jar support, which assumes that the jruby-complete.jar is always directly available as a file in its own right.

To deal with any problematic libraries, you can flag that specific nested jars should be automatically unpacked when the executable jar first runs.
Such nested jars are written beneath the temporary directory identified by the java.io.tmpdir system property.

Care should be taken to ensure that your operating system is configured so that it will not delete the jars that have been unpacked to the temporary directory while the application is still running.

For example, to indicate that JRuby should be flagged for unpacking by using the Maven Plugin, you would add the following configuration:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <requiresUnpack>
                    <dependency>
                        <groupId>org.jruby</groupId>
                        <artifactId>jruby-complete</artifactId>
                    </dependency>
                </requiresUnpack>
            </configuration>
        </plugin>
    </plugins>
</build>

16.7. Create a Non-executable JAR with Exclusions

Often, if you have an executable and a non-executable jar as two separate build products, the executable version has additional configuration files that are not needed in a library jar.
For example, the application.yml configuration file might be excluded from the non-executable JAR.

In Maven, the executable jar must be the main artifact and you can add a classified jar for the library, as follows:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <executions>
                <execution>
                    <id>lib</id>
                    <phase>package</phase>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <classifier>lib</classifier>
                        <excludes>
                            <exclude>application.yml</exclude>
                        </excludes>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

16.8. Remote Debug a Spring Boot Application Started with Maven

To attach a remote debugger to a Spring Boot application that was started with Maven, you can use the jvmArguments property of the maven plugin.

16.9. Build an Executable Archive From Ant without Using spring-boot-antlib

To build with Ant, you need to grab dependencies, compile, and then create a jar or war archive.
To make it executable, you can either use the spring-boot-antlib module or you can follow these instructions:

  1. If you are building a jar, package the application’s classes and resources in a nested BOOT-INF/classes directory.
    If you are building a war, package the application’s classes in a nested WEB-INF/classes directory as usual.

  2. Add the runtime dependencies in a nested BOOT-INF/lib directory for a jar or WEB-INF/lib for a war.
    Remember not to compress the entries in the archive.

  3. Add the provided (embedded container) dependencies in a nested BOOT-INF/lib directory for a jar or WEB-INF/lib-provided for a war.
    Remember not to compress the entries in the archive.

  4. Add the spring-boot-loader classes at the root of the archive (so that the Main-Class is available).

  5. Use the appropriate launcher (such as JarLauncher for a jar file) as a Main-Class attribute in the manifest and specify the other properties it needs as manifest entries — principally, by setting a Start-Class property.

The following example shows how to build an executable archive with Ant:

<target name="build" depends="compile">
    <jar destfile="target/${ant.project.name}-${spring-boot.version}.jar" compress="false">
        <mappedresources>
            <fileset dir="target/classes" />
            <globmapper from="*" to="BOOT-INF/classes/*"/>
        </mappedresources>
        <mappedresources>
            <fileset dir="src/main/resources" erroronmissingdir="false"/>
            <globmapper from="*" to="BOOT-INF/classes/*"/>
        </mappedresources>
        <mappedresources>
            <fileset dir="${lib.dir}/runtime" />
            <globmapper from="*" to="BOOT-INF/lib/*"/>
        </mappedresources>
        <zipfileset src="${lib.dir}/loader/spring-boot-loader-jar-${spring-boot.version}.jar" />
        <manifest>
            <attribute name="Main-Class" value="org.springframework.boot.loader.JarLauncher" />
            <attribute name="Start-Class" value="${start-class}" />
        </manifest>
    </jar>
</target>

17. Traditional Deployment

Spring Boot supports traditional deployment as well as more modern forms of deployment.
This section answers common questions about traditional deployment.

17.1. Create a Deployable War File

Because Spring WebFlux does not strictly depend on the servlet API and applications are deployed by default on an embedded Reactor Netty server, War deployment is not supported for WebFlux applications.

The first step in producing a deployable war file is to provide a SpringBootServletInitializer subclass and override its configure method.
Doing so makes use of Spring Framework’s servlet 3.0 support and lets you configure your application when it is launched by the servlet container.
Typically, you should update your application’s main class to extend SpringBootServletInitializer, as shown in the following example:

Java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MyApplication.class);
    }

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

}

Kotlin

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.boot.runApplication
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer

@SpringBootApplication
class MyApplication : SpringBootServletInitializer() {

    override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
        return application.sources(MyApplication::class.java)
    }

}

fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}

The next step is to update your build configuration such that your project produces a war file rather than a jar file.
If you use Maven and spring-boot-starter-parent (which configures Maven’s war plugin for you), all you need to do is to modify pom.xml to change the packaging to war, as follows:

<packaging>war</packaging>

If you use Gradle, you need to modify build.gradle to apply the war plugin to the project, as follows:

The final step in the process is to ensure that the embedded servlet container does not interfere with the servlet container to which the war file is deployed.
To do so, you need to mark the embedded servlet container dependency as being provided.

If you use Maven, the following example marks the servlet container (Tomcat, in this case) as being provided:

<dependencies>
    <!-- ... -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <!-- ... -->
</dependencies>

If you use Gradle, the following example marks the servlet container (Tomcat, in this case) as being provided:

dependencies {
    // ...
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    // ...
}
providedRuntime is preferred to Gradle’s compileOnly configuration.
Among other limitations, compileOnly dependencies are not on the test classpath, so any web-based integration tests fail.

If you use the Spring Boot build tools, marking the embedded servlet container dependency as provided produces an executable war file with the provided dependencies packaged in a lib-provided directory.
This means that, in addition to being deployable to a servlet container, you can also run your application by using java -jar on the command line.

17.2. Convert an Existing Application to Spring Boot

To convert an existing non-web Spring application to a Spring Boot application, replace the code that creates your ApplicationContext and replace it with calls to SpringApplication or SpringApplicationBuilder.
Spring MVC web applications are generally amenable to first creating a deployable war application and then migrating it later to an executable war or jar.
See the Getting Started Guide on Converting a jar to a war.

To create a deployable war by extending SpringBootServletInitializer (for example, in a class called Application) and adding the Spring Boot @SpringBootApplication annotation, use code similar to that shown in the following example:

Java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        // Customize the application or call application.sources(...) to add sources
        // Since our example is itself a @Configuration class (through
        // @SpringBootApplication)
        // we actually do not need to override this method.
        return application;
    }


}

Kotlin

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.boot.runApplication
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer

@SpringBootApplication
class MyApplication : SpringBootServletInitializer() {

    override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
        // Customize the application or call application.sources(...) to add sources
        // Since our example is itself a @Configuration class (through @SpringBootApplication)
        // we actually do not need to override this method.
        return application
    }

}

Remember that, whatever you put in the sources is merely a Spring ApplicationContext.
Normally, anything that already works should work here.
There might be some beans you can remove later and let Spring Boot provide its own defaults for them, but it should be possible to get something working before you need to do that.

Static resources can be moved to /public (or /static or /resources or /META-INF/resources) in the classpath root.
The same applies to messages.properties (which Spring Boot automatically detects in the root of the classpath).

Vanilla usage of Spring DispatcherServlet and Spring Security should require no further changes.
If you have other features in your application (for instance, using other servlets or filters), you may need to add some configuration to your Application context, by replacing those elements from the web.xml, as follows:

  • A @Bean of type Servlet or ServletRegistrationBean installs that bean in the container as if it were a <servlet/> and <servlet-mapping/> in web.xml.

  • A @Bean of type Filter or FilterRegistrationBean behaves similarly (as a <filter/> and <filter-mapping/>).

  • An ApplicationContext in an XML file can be added through an @ImportResource in your Application.
    Alternatively, cases where annotation configuration is heavily used already can be recreated in a few lines as @Bean definitions.

Once the war file is working, you can make it executable by adding a main method to your Application, as shown in the following example:

Java

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

Kotlin

fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}

If you intend to start your application as a war or as an executable application, you need to share the customizations of the builder in a method that is both available to the SpringBootServletInitializer callback and in the main method in a class similar to the following:

Java

import org.springframework.boot.Banner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return customizerBuilder(builder);
    }

    public static void main(String[] args) {
        customizerBuilder(new SpringApplicationBuilder()).run(args);
    }

    private static SpringApplicationBuilder customizerBuilder(SpringApplicationBuilder builder) {
        return builder.sources(MyApplication.class).bannerMode(Banner.Mode.OFF);
    }

}

Kotlin

import org.springframework.boot.Banner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer

@SpringBootApplication
class MyApplication : SpringBootServletInitializer() {

    override fun configure(builder: SpringApplicationBuilder): SpringApplicationBuilder {
        return customizerBuilder(builder)
    }

    companion object {

        @JvmStatic
        fun main(args: Array<String>) {
            customizerBuilder(SpringApplicationBuilder()).run(*args)
        }

        private fun customizerBuilder(builder: SpringApplicationBuilder): SpringApplicationBuilder {
            return builder.sources(MyApplication::class.java).bannerMode(Banner.Mode.OFF)
        }

    }

}

Applications can fall into more than one category:

  • Servlet 3.0+ applications with no web.xml.

  • Applications with a web.xml.

  • Applications with a context hierarchy.

  • Applications without a context hierarchy.

All of these should be amenable to translation, but each might require slightly different techniques.

Servlet 3.0+ applications might translate pretty easily if they already use the Spring Servlet 3.0+ initializer support classes.
Normally, all the code from an existing WebApplicationInitializer can be moved into a SpringBootServletInitializer.
If your existing application has more than one ApplicationContext (for example, if it uses AbstractDispatcherServletInitializer) then you might be able to combine all your context sources into a single SpringApplication.
The main complication you might encounter is if combining does not work and you need to maintain the context hierarchy.
See the entry on building a hierarchy for examples.
An existing parent context that contains web-specific features usually needs to be broken up so that all the ServletContextAware components are in the child context.

Applications that are not already Spring applications might be convertible to Spring Boot applications, and the previously mentioned guidance may help.
However, you may yet encounter problems.
In that case, we suggest asking questions on Stack Overflow with a tag of spring-boot.

17.3. Deploying a WAR to WebLogic

To deploy a Spring Boot application to WebLogic, you must ensure that your servlet initializer directly implements WebApplicationInitializer (even if you extend from a base class that already implements it).

A typical initializer for WebLogic should resemble the following example:

Java

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.WebApplicationInitializer;

@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {

}

Kotlin

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
import org.springframework.web.WebApplicationInitializer

@SpringBootApplication
class MyApplication : SpringBootServletInitializer(), WebApplicationInitializer

If you use Logback, you also need to tell WebLogic to prefer the packaged version rather than the version that was pre-installed with the server.
You can do so by adding a WEB-INF/weblogic.xml file with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app
    xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        https://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd
        http://xmlns.oracle.com/weblogic/weblogic-web-app
        https://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
    <wls:container-descriptor>
        <wls:prefer-application-packages>
            <wls:package-name>org.slf4j</wls:package-name>
        </wls:prefer-application-packages>
    </wls:container-descriptor>
</wls:weblogic-web-app>

The developers love spring Boot because it’s out of the box defaults. But sometimes, the developers may need to change these default values. Out of these, The most common one is to change the default port number of embedded web servers in spring boot.

So let’s check out the various ways to override the default port of a spring boot applications.

1. Using Configuration files

The most common and easier way to override default configurations is via properties files. To change the port number you should use the server.port property.

For example, you can change the port number to 8081 as shown below.

server.port=8081

Code language: Properties (properties)

You can also use the same configuration in application.yml files.

server: port: 8081

Code language: YAML (yaml)

1.1. Profile Specific port change

It is also possible to change the port based on the active spring profile.

To demonstrate this, We can create an application-qa.properties with port 9090.

server.port=9090

Code language: Properties (properties)

Also for uat, you could create another file called application-uat.properties with port 9091.

server.port=9091

Code language: Properties (properties)

By running the same application with different profiles, you can switch between different ports. With no active profiles, Spring Boot will pick the default port.

2. Using Command Line arguments

There are two ways you can pass the port number to application via command line. They are,

  1. Program parameters.
  2. JVM parameters.

2.1 Port change using spring program parameters

Application or program parameters are the ones that you pass using double dash(–) while calling JAR files.

$ java -jar hello-world.jar --server.port=8082

Be aware that the program parameters will override values in the properties files.

2.2 Port change using JVM arguments

You could also pass the settings as JVM arguments as shown below.

java -Dserver.port=8080 -jar hello-world.jar

3. Using Environment Variables

If you add a SERVER_PORT environment variable to your OS settings, Spring Boot will pick the port number from there.

For windows,

set SERVER_PORT=8081 java -jar hello-world.jar

Code language: Bash (bash)

For Linux/Mac,

export SERVER_PORT=8081<br>java -jar hello-world.jar

Code language: Bash (bash)

Twilio has a good article for env variables on Windows/Linux and Mac if you would like to read more.

Also note that this approach is best when used with Docker images as it is easier to pass environment variables to a docker runtime instead of external properties files.

4. Programatical approach to change the port

At the end, Spring boot needs to create the server with a given port. But if we could provide a WebServerFactoryCustomizer bean with a hard coded port number.

@Bean WebServerFactoryCustomizer<ConfigurableWebServerFactory> getWebServerFactoryCustomizer() { return factory -> factory.setPort(9090); }

Code language: Java (java)

Even though this is possible, Never do this in your production code. This is because you can’t override this value without another code change. Pick any one of those approaches from the above list.

5. The order of evaluation

As we have seen different approaches here, There may be situations where you may need to club these options together. In such cases, Spring Boot will evaluate the port number in the following order. Higher on this list is preferred the most.

  1. Hard-Coded Value from WebServerFactoryCustomizer
  2. Commandline arguments
  3. OS environment variables
  4. A profile specific application.properties
  5. application properties

There are also minor variants to these approaches which you can find at the external configurations section of spring boot documentation.

5. Summary

To summarize, we learned 4 different ways in which we can change the server port of a spring boot application. If you liked this article please give a read on the following writeups.

Like this post? Please share to your friends:
  • Как изменить порт rdp на клиенте
  • Как изменить порядок контекстного меню
  • Как изменить порт rdp windows server 2019
  • Как изменить порядок каналов на триколор тв
  • Как изменить порядок каналов на телевизоре филипс