What Is Spring Boot - Autoconfigurations In-Depth PDF
What Is Spring Boot - Autoconfigurations In-Depth PDF
Introduction
It looks like everyone and their grandma are using
Spring Boot to build projects. But very few can
answer the question: "What is Spring Boot?"
A quick caveat
I can give you a 99,99% guarantee, that you’d rather
want to read the What is Spring Framework? article
rst, if…:
Quick Links
Introduction …you are completely new to Spring Boot (or
Spring Boot Java).
Basics:
Conditionals …you think " Spring Framework, Spring Web
MVC and Spring Boot are all the same".
Spring Boot:
i
AutoCon guratio
…you think "Cut all this other crap, I just want
Spring Boot: to learn about Spring Boot!".
Dependencies
(Especially if you think "cut all this other crap").
FAQ
Fin Take the time to nish the previous article rst, then
Acknowledgment come back here.
Let’s start.
How to share
ApplicationContextCon gurations?
Imagine you are working for ReallyBigCompany™ with
a couple of teams working on di erent Spring
projects or products. But you are not using Spring
Boot, just plain Spring Framework.
@Configuration
@Import(ReallyBigCompanySharedConfiguration.class)
// (1)
public class
EarlyExitUnicornProjectContextConfiguration {
// (2)
}
annotation?
The Spring Framework o ers the @Conditional
annotation since version 4.0 (released on 2013). You
can put it on @Bean methods, @Components or
even @Con gurations and it looks like so:
@Conditional(SomeCondition.class) // (1)
@Configuration
public class
ReallyBigCompanySharedContextConfiguration {
@Bean
@Conditional(IsRelationalDatabaseCondition.class)
// (1)
public ReallyBigCompanyProprietaryFlywayClone
flywayClone() {
return new
ReallyBigCompanyProprietaryFlywayClone();
}
}
1. It is exactly the same ContextCon guration as
before, only now your @Bean method is also
annotated with a condition that we have yet to
write.
What could this condition look like?
Implementing a Spring Condition
package com.marcobehler;
import
org.springframework.context.annotation.Condition;
import
org.springframework.context.annotation.ConditionConte
import
org.springframework.core.type.AnnotatedTypeMetadata;
@Override
public boolean matches(ConditionContext
context, AnnotatedTypeMetadata metadata) { // (1)
return oracleJdbcDriverOnClassPath() &&
databaseUrlSet(context); // (2)
}
private boolean
databaseUrlSet(ConditionContext context) { // (3)
return
context.getEnvironment().containsProperty("spring.dat
Class.forName("oracle.jdbc.driver.OracleDriver");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}
Spring Boot:
AutoConfigurations
import org.springframework.boot.SpringApplication;
import
org.springframework.boot.autoconfigure.SpringBootAppl
@SpringBootApplication
public class MySpringBootApp {
SpringApplication.run(MySpringBootApp.class,
args);
}
1. Auto-registered @PropertySources
You can tell any plain Spring Framework application
to read in .properties les from basically any location
you want, with the help of the @PropertySource
annotation.
@PropertySource(value =
"classpath:application.properties",
ignoreResourceNotFound = true)
2. Read-in META-INF/spring.factories
Every Spring Boot project has a dependency on the
following library: org.springframework.boot:spring-
boot-autocon gure. It is a simple .jar le containing
pretty much all of Spring Boot’s magic.
org.springframework.boot.autoconfigure.admin.SpringAp
org.springframework.boot.autoconfigure.aop.AopAutoCon
org.springframework.boot.autoconfigure.amqp.RabbitAut
org.springframework.boot.autoconfigure.batch.BatchAut
org.springframework.boot.autoconfigure.cache.CacheAut
org.springframework.boot.autoconfigure.cassandra.Cas
org.springframework.boot.autoconfigure.cloud.CloudSe
org.springframework.boot.autoconfigure.context.Config
org.springframework.boot.autoconfigure.context.Messag
org.springframework.boot.autoconfigure.context.Prope
org.springframework.boot.autoconfigure.couchbase.Couc
org.springframework.boot.autoconfigure.dao.Persistenc
@ConditionalOnBean(DataSource.class). The
condition is true only if the user speci ed a
DataSource @Bean in a @Con guration.
@ConditionalOnClass(DataSource.class). The
condition is true if the DataSource class is on
the classpath.
@ConditionalOnCloudPlatform(CloudPlatform.Heroku).
The condition is true if the CloudPlatform is set
to Heroku.
@ConditionalOnExpression("someSpELExpression).
The condition is true if the SpEL expression is
true.
@ConditionalOnJava(JavaVersion.EIGHT). The
condition is true if the current Java version is 8.
@ConditionalOnJndi("java:comp/env/ejb/myEJB").
The condition is true if the speci ed JNDI
context exists.
@ConditionalOnMissingBean(DataSource.class).
The condition is true if the user did not specify
a DataSource @Bean in any @Con guration.
@ConditionalOnMissingClass(DataSource.class).
The condition is true if the DataSource class is
not on the classpath.
@ConditionalOnNotWebApplication. The
condition is true if the application is not a web
application.
@ConditionalOnProperty("my.property"). The
condition is true if my.property is set.
@ConditionalOnResource("classpath:my.properties").
The condition is true if my.properties exists.
@ConditionalOnSingleCandidate(DataSource.class).
Matches if there is exactly one primary
DataSource bean speci ed in your application.
Summary
When Spring Boot boots up:
@Configuration(proxyBeanMethods = false)
@Conditional(EmbeddedDatabaseCondition.class)
@ConditionalOnMissingBean({
DataSource.class, XADataSource.class })
@Import(EmbeddedDataSourceConfiguration.class)
protected static class
EmbeddedDatabaseConfiguration {
@Configuration(proxyBeanMethods = false)
// (4)
@Conditional(PooledDataSourceCondition.class) //
(5)
@ConditionalOnMissingBean({
DataSource.class, XADataSource.class }) // (6)
@Import({
DataSourceConfiguration.Hikari.class,
DataSourceConfiguration.Tomcat.class, // (7)
DataSourceConfiguration.Dbcp2.class,
DataSourceConfiguration.Generic.class,
DataSourceJmxConfiguration.class })
protected static class
PooledDataSourceConfiguration {
// some more
}
@Bean // (5)
@ConfigurationProperties(prefix =
"spring.datasource.hikari")
HikariDataSource
dataSource(DataSourceProperties properties) {
HikariDataSource
dataSource = createDataSource(properties,
HikariDataSource.class);
if
(StringUtils.hasText(properties.getName())) {
dataSource.setPoolName(properties.getName());
}
return dataSource;
}
And if you are done with that, you can have a look at
the AutoCon guration for one of your favorite
libraries, like Flyway, or Jackson, or MongoDB.
2. @ConditionalOnProperty. Self-explanatory.
Analyzing spring-boot-starter-web
The one dependency every web-based Spring Boot
project includes, is the spring-boot-starter-web
dependency. Its pom.xml le looks like this:
<dependencies>
<!-- other dependencies left out
for conciseness -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-
starter-tomcat</artifactId> <!-- 1 -->
</dependency>
<!-- other dependencies left out
for conciseness -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-
webmvc</artifactId> <!-- 2 -->
</dependency>
</dependencies>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-
core</artifactId> <!-- 1 -->
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-annotations-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- other dependencies left out
for conciseness -->
</dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.12.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
That is because the Spring Boot project that is
generated by Spring’s Initializr extends from a parent
project called spring-boot-dependencies. It is not so
much of a project, but a simple pom.xml le.
And in that pom.xml le, you have a huge
dependencyManagement section (covering every 3rd
party library Spring Boot integrates with), which
de nes dependencies that you can include in your
pom.xml le, without specifying the version number.
Because it is already speci ed in that parent
pom.xml.
<properties>
<hibernate.version>5.4.12.Final</hibernate.version>
<!-- 1 -->
<!-- other versions left out for brevity -->
</properties>
FAQ
or
spring.autoconfigure.exclude=org.springframework.boot
Fin
Hopefully this article sheds some light on what
Spring Boot is. Some nal thoughts:
Acknowledgments
A big "thank you" goes out to Patricio "Pato"
Moschcovich, who not only did the proofreading for
this article but also provided invaluable feedback!
e.g. [email protected]
I want more!
Share:
Comments
Login
Add a comment
Anonymous
? 0 points · 56 days ago
Anonymous
?
? 0 points · 56 days ago
Istiaq Hossain
I 0 points · 55 days ago
Anonymous
? 0 points · 55 days ago
belen.emre
B 0 points · 54 days ago
Great article! Thanks a lot for the enjoyable language and thank for
getting us being used to read FAQs :)
Anonymous
? 0 points · 49 days ago
Anonymous
? 0 points · 53 days ago
maks.mephi
0 points · 26 days ago
Anonymous
? 0 points · 43 days ago
Great article, thank you! Hope to see more of them in the future
maks.mephi
0 points · 26 days ago
Cool article!
Anonymous
? 0 points · 18 days ago
Powered by Commento
Privacy & Terms | Imprint | Contact