Spring Boot Concepts: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
(Created page with "=Internal= * Spring")
 
 
(140 intermediate revisions by the same user not shown)
Line 1: Line 1:
=Internal=
=Internal=


* [[Spring#Subjects|Spring]]
* [[Spring Boot#Subjects|Spring Boot]]
* [[Spring Dependency Injection and Inversion of Control Container Concepts]]
 
=Spring Project Structure=
 
{{Internal|Spring_Initializr#Spring_Project_Structure|Spring Initializr Project Structure}}
 
=Component Scanning=
 
[[@SpringBootApplication]] annotation implies [[@ComponentScan]] for the package the main application class belongs to, and all its sub-packages. Those packages are automatically scanned for components. If there are components in other packages which are not sub-packages of the main package, they can be manually added in form of individual  [[@ComponentScan]] annotations:
 
<syntaxhighlight lang='java'>
@SpringBootApplication
@ComponentScans(@ComponentScan(basePackages = "some.experimental.dependency"))
public class MainApplication {
  ...
}
</syntaxhighlight>
 
Note that the extra package specification is additive, we don't need to redundantly specify the main application class package, which is implied by [[@SpringBootApplication]].
 
{{External|[https://github.com/ovidiuf/playground/tree/master/spring/spring-boot/spring-boot-with-dependency-%40ComponentScan-in-main-app Playground SpringBoot @ComponentScan Example]}}
 
For general considerations on component scanning, as they apply to the Spring Framework in general, see: {{Internal|Spring_Dependency_Injection_and_Inversion_of_Control_Container_Concepts#Component_Scanning|Spring Dependency Injection and  Inversion of Control Container Concepts - Component Scanning}}
 
=Autoconfiguration=
 
With autoconfiguration, Spring Boot can make reasonable guesses of what components need to be configured and wired together based on the classpath content, environment variables and other factors. Based on these, Spring Boot provides basic configuration needed to configure the application, usually with known frameworks. Autoconfiguration is enabled by the [[@EnableAutoConfiguration]] annotation, which is implied by [[@SpringBootApplication]]. When the application starts, Spring Boot autoconfiguration detects libraries such as Spring MVC, Tomcat, SQL databases and configures the application bean with the right dependencies. For example, if we add Spring Boot Started Web as dependency in the project, Spring Boot autoconfiguration sees that Spring MVC is on the classpath and it autoconfigures the dispatcher servlet, a default error page and /webjars. Same for Spring Boot Data JPA starter: autoconfiguration configures a Data Source and an Entity Manager.
 
The autoconfiguration logic is implemented in spring-boot-autoconfigure.jar. The JAR contains packages for known frameworks and pattern. An important file in spring-boot-autoconfigure.jar is /META-INF/spring-factories. This file lists all the autoconfiguration classes that should be enabled under the org.springframework.boot.autoconfigure.EnableAutoConfiguration key. <font color=darkgray>TODO process this http://www.springboottutorial.com/spring-boot-auto-configuration</font>.
 
Autoconfiguration classes can be bundled in external JARs and still be picked up by Spring Boot. <font color=darkgray>TODO process this https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html, https://github.com/spring-projects/spring-boot/blob/v2.1.0.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories.</font>
 
<font color=darkgray>
TODO PROCESS:
* What is Spring Boot Auto Configuration? http://www.springboottutorial.com/spring-boot-auto-configuration
* Spring Boot Documentation - Creating your Own Autoconfiguration https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
* META-INF/spring.factories Example https://github.com/spring-projects/spring-boot/blob/v2.1.0.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
 
* Database Autoconfiguration:
** https://github.com/spring-projects/spring-boot/blob/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java
** https://github.com/spring-projects/spring-boot/blob/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java
 
</font>
==DataSource Autoconfiguration==
 
{{Internal|Spring Boot DataSource Autoconfiguration|Spring Boot DataSource Autoconfiguration}}
 
==Embedded Web Server Autoconfiguration==
 
{{Internal|Spring Boot Embedded Web Server Autoconfiguration|Spring Boot Embedded Web Server Autoconfiguration}}
 
=<span id='Developer_Tools'></span><span id='DevTools'></span>Developer Tools (DevTools)=
 
Additional set of tools that come as part of Spring Boot, and which can make, according to the documentation, "development experience a little more pleasant". The artifacts are identified as <tt>org.springframework.boot:spring-boot-devtools</tt>. They include the following development-time features:
* automatic application restart when Java code or property files change. This is implemented by loading everything that is maintained in src/main, such as application classes and property files, with a special classloader. This classloader monitors changes and reloads the new classes and restarts the application context when a change is detected. The other classloader loads dependency libraries.
* automatic browser refresh when browser resources (templates, JavaScript, stylesheets, etc.) change. <font color=darkgray>More details in [[SIA]] page 24.</font>
* automatic disable of template caches
* built-in H2 console, which can be used agains the H2 database, it deployed. For more details see:
{{Internal|SpringBoot DevTools H2 Console|SpringBoot DevTools H2 Console}}
 
Development tools are self-disable when the application runs in production settings, such as when running as a fully packaged application (such as with <tt>java -jar</tt>).
 
<font color=darkgray>They should be declared optional in [[Maven]] or "compileOnly" in Gradle</font>.
 
Use:
 
<syntaxhighlight lang='groovy'>
dependencies {
    runtimeOnly('org.springframework.boot:spring-boot-devtools')
}
</syntaxhighlight>
 
=Configuration Processor=
 
<font color=darkgray>TO process: https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#configuration-metadata-annotation-processor</font>.
 
=Spring Boot Dependency Management=
 
A Spring Boot project manages dependencies differently than a [[Spring_Framework#Spring_Framework_Dependency_Management|bare Spring Framework project]]. <font color=darkgray>TODO more details about the concepts behind dependency management with SpringBoot.</font>
 
==Spring Boot Starter Dependency==
 
A Spring Boot starter is a dependency that has the word "starter" in their artifact ID. They are special dependency that typically do not have any library code themselves, but instead transitively pull in other libraries. The starter dependency pattern insures that the build file will be significantly smaller and easier to manage because we don't need to declare dependencies on all libraries needed. It allows to think of dependencies in terms of what capabilities they provide, rather than in term of library names. Also, no library version specification is necessary. Spring Boot will come with specific values and will insure they are transitively compatible. The only version that needs to be specified is the Spring Boot version.
 
'org.springframework.boot:spring-boot-starter' is included in all other starters.
 
Example:
 
<syntaxhighlight lang='groovy'>
dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
}
</syntaxhighlight>
 
<font color='darkgray'>
TODO/PROCESS:
* How do I see what's in a starter?
* Spring Boot documentation - Create your own starter: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html#boot-features-custom-starter
* Baeldung - Creating a Custom Starter with Spring Boot https://www.baeldung.com/spring-boot-custom-starter
</font>
 
=<span id='Persistence_Initialization'>Spring Boot Database Initialization=
 
Also see: {{Internal|Spring_Persistence_Concepts#Database_Initialization|Spring Persistence Concepts - Database Initialization}} {{Internal|Spring_Boot_DataSource_Autoconfiguration|Spring Boot DataSource Autoconfiguration}}
 
 
SpringBoot database initialization is an alternate database initialization mechanism that can be used '''instead''' of [[Spring_Data_JPA#Generic_JPA_Database_Initialization|Generic JPA Database Initialization]] or [[Spring_Data_JPA#Database_Initialization_Using_Hibernate|Database Initialization Using Hibernate]], for JPA persistence. For non-JPA persistence, SpringBoot does not compete with those mechanisms and it is probably the preferred way to initialize the database. For JPA applications, make sure to turn off JPA database initialization with:
<syntaxhighlight lang='text'>spring.jpa.hibernate.ddl-auto=none</syntaxhighlight>
 
Spring Boot Database Initialization uses files <span id='schema.sql'></span><tt>schema.sql</tt> and <span id='data.sql'></span><tt>data.sql</tt> if found in the standard root classpath locations. If <tt>schema.sql</tt> is found in the root of the application's classpath, Spring Boot will execute the DDL found in that file and will create the schema in the database. To include the file into the application JAR, place it in src/main/resources. If <tt>data.sql</tt> is found in the root of the application's classpath, Spring Boot will execute the DML found in the file  against the database when the application starts and will populate the tables created with [[#schema.sql|schema.sql]].  To include the file into the application JAR, place it in src/main/resources.
 
By default, Spring Boot Database will execute DDL and DML from <tt>schema.sql</tt>/<tt>data.sql</tt> only on embedded databases. However, this behavior can be customized by specifying the following application configuration property:
<syntaxhighlight lang='text'>
spring.datasource.initialization-mode=always
</syntaxhighlight>
 
Per-vendor behavior can be specified using:
<syntaxhighlight lang='text'>
spring.datasource.platform=hsqldb|h2|oracle|mysql|postgresql
</syntaxhighlight>
and naming postfixing the schema and data files with the value specified in the configuration: <tt>schema-${platform}.sql</tt>, <tt>data-${platform}.sql</tt>. If both <tt>data.sql</tt> and <tt>data-${platform}.sql</tt> exist, both will be executed.
 
By default, Spring Boot enables the fail-fast feature of the Spring JDBC initializer. This means that, if the scripts cause exceptions, the application fails to start. You can tune that behavior by setting:
<syntaxhighlight lang='text'>
spring.datasource.continue-on-error=true
</syntaxhighlight>
 
=Logging=
 
{{Internal|Spring Boot Logging#Overview|Spring Boot Logging}}
 
=Caching=
 
Spring Boot automatically configures a suitable cache manager to serve as provider for the relevant cache.
 
<font color=darkgray>TODO: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html. Also see [[Spring_Framework#Cache]].</font>
 
=Spring Boot Plugins=
 
==Spring Boot Gradle Plugin==
 
{{Internal|Spring Boot Gradle Plugin#Overview|Spring Boot Gradle Plugin}}
==Spring Boot Maven Plugin==
 
=IntelliJ Support=
 
{{Internal|IntelliJ IDEA Plugin for Spring Boot#Overview|IntelliJ IDEA Plugin for Spring Boot}}
 
=<span id='SpringBoot_Test_Example'></span><span id='Testing_Logging_Configuration'></span><span id='Spring_Boot_Mockito_Support'></span>Testing=
 
{{Internal|Spring Boot Testing Concepts#Overview|Spring Boot Testing Concepts}}
 
=Actuator=
 
{{Internal|Spring_Boot_Actuator|Spring Boot Actuator}}
 
=Spring Boot CLI=
 
{{Internal|Spring_Boot_CLI|Spring Boot CLI}}
 
=Spring Boot Application Context=
 
One improvement brought forward by Spring Boot is that Spring Boot applications are not required to [[Spring_Dependency_Injection_and_Inversion_of_Control_Container_Concepts#Application_Context|explicitly create their application context]]. The Spring Boot runtime transparently creates it.
 
=Spring Boot Main Class=
 
The Spring Boot '''main class''', also know as the '''bootstrap class''', bootstraps the project. It lives under [[Spring_Initializr#Spring_Project_Structure|src/main/java]]. It is a class that contains a main method to be executed when the Spring Boot JAR artifact is run. The class is annotated with [[@SpringBootApplication]].
 
<syntaxhighlight lang='java'>
package ...;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class ExampleApplication {
 
    public static void main(String[] args) {
 
        // SpringApplication performs the bootstrapping of the application.
        // It gets a configuration class and the command-line arguments.
        SpringApplication.run(ExampleApplication.class, args);
    }
}
</syntaxhighlight>
 
=Spring Boot Property Injection=
 
{{Internal|Spring Boot Property Injection|Spring Boot Property Injection}}

Latest revision as of 22:19, 14 January 2019

Internal

Spring Project Structure

Spring Initializr Project Structure

Component Scanning

@SpringBootApplication annotation implies @ComponentScan for the package the main application class belongs to, and all its sub-packages. Those packages are automatically scanned for components. If there are components in other packages which are not sub-packages of the main package, they can be manually added in form of individual @ComponentScan annotations:

@SpringBootApplication
@ComponentScans(@ComponentScan(basePackages = "some.experimental.dependency"))
public class MainApplication {
  ...
}

Note that the extra package specification is additive, we don't need to redundantly specify the main application class package, which is implied by @SpringBootApplication.

Playground SpringBoot @ComponentScan Example

For general considerations on component scanning, as they apply to the Spring Framework in general, see:

Spring Dependency Injection and Inversion of Control Container Concepts - Component Scanning

Autoconfiguration

With autoconfiguration, Spring Boot can make reasonable guesses of what components need to be configured and wired together based on the classpath content, environment variables and other factors. Based on these, Spring Boot provides basic configuration needed to configure the application, usually with known frameworks. Autoconfiguration is enabled by the @EnableAutoConfiguration annotation, which is implied by @SpringBootApplication. When the application starts, Spring Boot autoconfiguration detects libraries such as Spring MVC, Tomcat, SQL databases and configures the application bean with the right dependencies. For example, if we add Spring Boot Started Web as dependency in the project, Spring Boot autoconfiguration sees that Spring MVC is on the classpath and it autoconfigures the dispatcher servlet, a default error page and /webjars. Same for Spring Boot Data JPA starter: autoconfiguration configures a Data Source and an Entity Manager.

The autoconfiguration logic is implemented in spring-boot-autoconfigure.jar. The JAR contains packages for known frameworks and pattern. An important file in spring-boot-autoconfigure.jar is /META-INF/spring-factories. This file lists all the autoconfiguration classes that should be enabled under the org.springframework.boot.autoconfigure.EnableAutoConfiguration key. TODO process this http://www.springboottutorial.com/spring-boot-auto-configuration.

Autoconfiguration classes can be bundled in external JARs and still be picked up by Spring Boot. TODO process this https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html, https://github.com/spring-projects/spring-boot/blob/v2.1.0.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories.

TODO PROCESS:

DataSource Autoconfiguration

Spring Boot DataSource Autoconfiguration

Embedded Web Server Autoconfiguration

Spring Boot Embedded Web Server Autoconfiguration

Developer Tools (DevTools)

Additional set of tools that come as part of Spring Boot, and which can make, according to the documentation, "development experience a little more pleasant". The artifacts are identified as org.springframework.boot:spring-boot-devtools. They include the following development-time features:

  • automatic application restart when Java code or property files change. This is implemented by loading everything that is maintained in src/main, such as application classes and property files, with a special classloader. This classloader monitors changes and reloads the new classes and restarts the application context when a change is detected. The other classloader loads dependency libraries.
  • automatic browser refresh when browser resources (templates, JavaScript, stylesheets, etc.) change. More details in SIA page 24.
  • automatic disable of template caches
  • built-in H2 console, which can be used agains the H2 database, it deployed. For more details see:
SpringBoot DevTools H2 Console

Development tools are self-disable when the application runs in production settings, such as when running as a fully packaged application (such as with java -jar).

They should be declared optional in Maven or "compileOnly" in Gradle.

Use:

dependencies {
    runtimeOnly('org.springframework.boot:spring-boot-devtools')
}

Configuration Processor

TO process: https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#configuration-metadata-annotation-processor.

Spring Boot Dependency Management

A Spring Boot project manages dependencies differently than a bare Spring Framework project. TODO more details about the concepts behind dependency management with SpringBoot.

Spring Boot Starter Dependency

A Spring Boot starter is a dependency that has the word "starter" in their artifact ID. They are special dependency that typically do not have any library code themselves, but instead transitively pull in other libraries. The starter dependency pattern insures that the build file will be significantly smaller and easier to manage because we don't need to declare dependencies on all libraries needed. It allows to think of dependencies in terms of what capabilities they provide, rather than in term of library names. Also, no library version specification is necessary. Spring Boot will come with specific values and will insure they are transitively compatible. The only version that needs to be specified is the Spring Boot version.

'org.springframework.boot:spring-boot-starter' is included in all other starters.

Example:

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
}

TODO/PROCESS:

Spring Boot Database Initialization

Also see:

Spring Persistence Concepts - Database Initialization
Spring Boot DataSource Autoconfiguration


SpringBoot database initialization is an alternate database initialization mechanism that can be used instead of Generic JPA Database Initialization or Database Initialization Using Hibernate, for JPA persistence. For non-JPA persistence, SpringBoot does not compete with those mechanisms and it is probably the preferred way to initialize the database. For JPA applications, make sure to turn off JPA database initialization with:

spring.jpa.hibernate.ddl-auto=none

Spring Boot Database Initialization uses files schema.sql and data.sql if found in the standard root classpath locations. If schema.sql is found in the root of the application's classpath, Spring Boot will execute the DDL found in that file and will create the schema in the database. To include the file into the application JAR, place it in src/main/resources. If data.sql is found in the root of the application's classpath, Spring Boot will execute the DML found in the file against the database when the application starts and will populate the tables created with schema.sql. To include the file into the application JAR, place it in src/main/resources.

By default, Spring Boot Database will execute DDL and DML from schema.sql/data.sql only on embedded databases. However, this behavior can be customized by specifying the following application configuration property:

spring.datasource.initialization-mode=always

Per-vendor behavior can be specified using:

spring.datasource.platform=hsqldb|h2|oracle|mysql|postgresql

and naming postfixing the schema and data files with the value specified in the configuration: schema-${platform}.sql, data-${platform}.sql. If both data.sql and data-${platform}.sql exist, both will be executed.

By default, Spring Boot enables the fail-fast feature of the Spring JDBC initializer. This means that, if the scripts cause exceptions, the application fails to start. You can tune that behavior by setting:

spring.datasource.continue-on-error=true

Logging

Spring Boot Logging

Caching

Spring Boot automatically configures a suitable cache manager to serve as provider for the relevant cache.

TODO: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html. Also see Spring_Framework#Cache.

Spring Boot Plugins

Spring Boot Gradle Plugin

Spring Boot Gradle Plugin

Spring Boot Maven Plugin

IntelliJ Support

IntelliJ IDEA Plugin for Spring Boot

Testing

Spring Boot Testing Concepts

Actuator

Spring Boot Actuator

Spring Boot CLI

Spring Boot CLI

Spring Boot Application Context

One improvement brought forward by Spring Boot is that Spring Boot applications are not required to explicitly create their application context. The Spring Boot runtime transparently creates it.

Spring Boot Main Class

The Spring Boot main class, also know as the bootstrap class, bootstraps the project. It lives under src/main/java. It is a class that contains a main method to be executed when the Spring Boot JAR artifact is run. The class is annotated with @SpringBootApplication.

package ...;

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

@SpringBootApplication
public class ExampleApplication {

    public static void main(String[] args) {

        // SpringApplication performs the bootstrapping of the application. 
        // It gets a configuration class and the command-line arguments.
        SpringApplication.run(ExampleApplication.class, args);
    }
}

Spring Boot Property Injection

Spring Boot Property Injection