Spring Boot - A Closer Look Lab - Spring Academy
Spring Boot - A Closer Look Lab - Spring Academy
Back To Course
S p r i n g B o o t - A C l o s e r Lo o k L a b Mark as Complete Next Lesson
Spring Boot - A Closer Look Lab - Spring Academy https://spring.academy/courses/spring-boot/lessons/spring-boot-closer-look-lab
Spring Boot S p r i n g B o o t - A C l o s e r Lo o k L a b
0 of 45 lessons completed
0%
# Purpose
Agenda 3m
In this lab you will go a level deeper into core Spring Boot concepts while "Bootifying" a previous version of the Rew
application.
MODULE 1
Spring Boot Feature
Introduction # Learning Outcomes
Demo -
Spring You will be using the 32-jdbc-autoconfig project.
Boot - A 24m
Closer Estimated time to complete: 45 minutes.
Look Lab
MODULE 3
# Prerequisites
Spring Boot - Spring
Data JPA
The prerequisites are included as part of the Introduction to the Spring Professional Learning Path course
lesson.
MODULE 4
Web Application with If you already completed it, you should be ready to do this lab. If not, assuming you already have JDK 11 or 17 insta
Spring Boot and Java IDE, you will need to do the following:
Conclusion 1. Bootify the application, meaning you will wrap the application with Spring Boot, and demonstrate how Spring B
simplifies your development experience through starters and auto-configuration.
2. Bootify the application's integration test.
3. Add a CommandLineRunner to demonstrate how Spring Boot can package and run an application with no
3. Add a CommandLineRunner to demonstrate how Spring Boot can package and run an application with no
additional runtime dependencies.
4. Demonstrate how to exclude an auto-configuration.
5. Demonstrate external configuration.
# Getting Started
You will also need a Terminal or Command window to run Maven or Gradle manually - IntelliJ/Eclipse/STS support
terminal window within the IDE.
Navigate to the parent directory containing the course projects (this is the lab directory of the code you cloned/
unzipped from github).
# Quick Instructions
If you are already knowledgeable with the lesson concepts, you may consider jumping right to the code, and execu
lab in form of embedded TODO comments. Instructions on how to view them are at the Using TODO Tasks
If you aren’t sure, try the TODO instructions first and refer to the lab instructions by TODO number if you need more
help.
# Instructions
• Navigate to the project, and run the full suite of tests to verify the build is successful and tests pass.
• Examine the pom.xml or build.gradle file of the project. What do you see for the project dependencies?
• You should see a set of libraries covering Spring Framework, JDBC and HSQLDB database
R e fa c to r to S t a r te r s
Part of the value point of Spring Boot is simplified dependency management. In this section, you will refactor from
discrete Spring Framework and 3rd party dependencies to the Spring Boot Starters.
• In your Terminal/Command window, run Maven goal or Gradle task for displaying dependencies. (The exampl
commands below assume you are running them at the lab directory.)
You will also see the spring-boot-starter as this is required for SpringApplication.run(
• You will also see the spring-boot-starter as this is required for SpringApplication.run(
whether you use the rest of Spring Boot or not.
• Add the Spring Boot plugin to the project's pom.xml or build.gradle file
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
You will see, as we build the project, Spring Boot plugin will generate the runtime deployment artifact for you
through the repackage goal for Maven and the bootJar task for Gradle. The repackage goal is run as par
the Maven package goal and the bootJar task is run as part of Gradle assemble task.
1. Remove the Spring JDBC and Spring Test dependencies from the project's pom.xml or build.gradle
2. Add the Spring Boot Starters for:
• JDBC
Hint: If you need help to understand the starter dependencies, take a look at the Spring Boot Intro
build.gradle that was generated by the Spring Initializr.
• Rerun the maven dependency:tree Maven goal or dependencies Gradle task for the project:
• What dependencies do you see now?
• You should now see the Boot starter dependencies instead.
Typically your Spring Boot pom.xml or build.gradle file is simpler than the original but this example is sufficien
simple that there is little difference.
C re a t e a S p r i n g B o o t A p p l i c a t i o n
1. You already have a RewardsApplication class provided for you. This is the shell for the Spring Boot
application.
2. Annotate the RewardsApplication class accordingly.
Hint: In your IDE, look at a decompiled version of the @SpringBootApplication annotation. (Or look at th
Hint: In your IDE, look at a decompiled version of the @SpringBootApplication annotation. (Or look at th
Javadoc of the annotation.)
3. Notice that a main() method has already been defined and the Spring boot classes initialized using
SpringApplication.run
In Spring Boot applications, the default files are schema.sql and data.sql and they must be in the
classpath root.
Note: You may choose to specify these files using properties (as described in the slides).
• The starting point of the project does not have a runner, so the files originally were provided to set up a te
data fixture.
You are moving the files from test/resources to main/resources so you can use the same files in
application runtime to demonstrate the CommandLineRunner.
TODO-05 : Setup a command line runner to print the Reward account count:
The Spring Boot CommandLineRunner and ApplicationRunner abstractions are guaranteed to run
before SpringApplication.run() method returns. Multiple runners may be configured, and can be ordered wi
@Order annotation.
C a p t u re P ro p e r t i e s I n t o a C l a s s
Spring Boot @ConfigurationProperties allows developer to map properties, especially properties with hierarc
structure, into a class.
rewards.recipient.name=John Doe
rewards.recipient.age=10
rewards.recipient.gender=Male
rewards.recipient.hobby=Tennis
RewardsRecipientProperties
@ConfigurationProperties(prefix = "rewards.recipient")
public class RewardsRecipientProperties {
4. Now use one of the 3 schemes below to enable @ConfigurationProperties (Feel free to try all of them.)
1. Add @EnableConfigurationProperties(RewardsRecipientProperties.class)
RewardsApplication class
@Bean
CommandLineRunner commandLineRunner2(RewardsRecipientProperties rewardsRecipien
return args -> System.out.println("Recipient: " + rewardsRecipientPropertie
}
1. Add debug=true property to your application.properties. This causes Spring Boot to log everything i
does and what auto-configuration choices it does and does not make.
2. Run the application. What do you see on the console?
3. You should see your log output from the command line runner:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:
-----------------
Do you see DataSourceAutoConfiguration under Positive matches? Now you know where the
DataSource came from.
1. Open SystemTestConfig.java.
2. Stop Spring invoking the dataSource() bean factory method by commenting out the @Bean annotation.
TODO-09 : Return to your IDE and refactor RewardNetworkTests into a Spring Boot Integration test:
1. Run this test without making any change, it will fail. It fails because the Spring Boot auto-configuration is not
enabled when the test is run.
2. Remove the @ContextConfiguration and
@ContextConfiguration(classes = {SystemTestConfig.class}) annotations.
3. Add @SpringBootTest annotation to run as a Spring Boot Test
• There is no need to specify the configuration class to use as the annotation will automatically
for any @Component (or @Configuration) classes in the current package or below. Since the
SystemTestConfig class is in the same package, it will be discovered and processed. This includes
processing the @Import annotation that references the RewardsConfig class containing all the other b
definitions.
• This is considered an End-To-End integration test, including the wired components.
Note that in a real production application you are most likely to configure an external database. Spring Bo
offers properties to do this.
4. Run the RewardNetworkTests and verify it succeeds.
5. Do an experimentation
• Specify the configuration class with @SpringBootTest like following:
@SpringBootTest(classes={SystemTestConfig.class})
• Run the test and observe that it fails. Think about why it fails.
The failure occurs because Spring Boot autoconfiguration is disabled: when you specify the configuration
class, @SpringBootTest stops searching for configuration class annotated with
@SpringBootConfiguration, which contains @EnableAutoConfiguration.
• Revert the change and verify the test succeeds again
You will dig deeper into Spring Boot Testing in a later unit.
Override Auto-Configuration
You have seen to this point that Spring Boot will detect and automatically configure a DataSource on your behalf.
how would this work if you needed to configure multiple databases from your application? In this case auto-configu
cannot really help you.
1. Use the default DataSource auto-configuration with supporting default configuration, and also explicitly set
additional DataSource beans with different names, as specified by the @Qualifier annotation. You can als
the order of precedence using the @Order annotation.
2. Disable auto-configuration for DataSource, and explicitly declare multiple DataSource beans using Java
Configuration.
We will use option 2 and disable the DataSource auto-configuration both programmatically and using configuratio
properties.
1. Add DataSource bean explicitly in the RewardsConfig class by by uncommenting the code.
• Note the debug log message, so we can tell if this method is being used.
2. Remove the code that injects DataSource bean since we no longer need it.
Note: Technically you don't have to disable data-source auto-configuration given that Spring Boot will use applicatio
defined DataSource bean over auto-configured one.
If so you just proved your dataSource was generated in your Java config.
• Do you see the DataSourceAutoConfiguration is no longer matched?
Exclusions:
-----------
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
Troubleshooting: If you experience BeanCurrentlyInCreationException, think about why that is the case an
how to solve it.
Notes for Thought: When you Bootified your application, did you auto-wire a JdbcTemplate? If you did, what migh
some implications for a multi-database solution? Would you need to remove use of an auto-wired JdbcTemplate? H
would you do this?
TODO-13 (Optional) : Let's see what the Spring Boot Maven/Gradle plugin is doing:
1. From either your IDE or your Terminal/Command window, execute the Maven package goal or Gradle
task.
The following leverages the parent project multi-module build with the maven/gradle wrapper, and is executed
the project root lab directory.
Notice that, when using Maven, it is necessary to skip the tests using the -Dmaven.test.skip=
the fact that you have not yet Bootified the testing portion of the project.
2. In 32-jdbc-autoconfig, a target directory (for Maven), or a build/libs directory (for Gradle) should n
exist. Review its contents, what do you see?
• You should see two generated JAR files:
• 32-jdbc-autoconfig-5.3.23.jar and
Notice that the "original" is much smaller. The other JAR is executable and contains all the necessary
dependencies (hence it is called a "fat" JAR!)
3. Extract the jar file to a temporary directory, and view the contents using jar.
Windows:
mkdir temp
copy *jdbc-autoconfig\target\*.jar temp (for Maven)
copy *jdbc-autoconfig\build\libs\*.jar temp (for Gradle)
cd temp
jar xvf *.jar
Linux or MacOS:
mkdir temp
cp *jdbc-autoconfig/target/*.jar temp (for Maven)
cp *jdbc-autoconfig/build/libs/*.jar temp (for Gradle)
cd temp
jar xvf *.jar
You will see the classpath resources, manifest file and supporting compile scope package classes are include
• Look carefully at the BOOT-INF directory.
• What do you see?
You should see the jar is generated to be run as a standalone application on your behalf:
• Contains all the necessary runtime dependencies - BOOT-INF holds all your compiled classes and all the
dependency jars.
• The manifest declares a main entry point (the Main-Class: property)
5. There are many ways to run this application, either directly using the JAR, using spring-boot:
Maven or in your IDE as you did earlier.
Look over the Running and Testing a Spring Boot Project article lesson discussing various options for running
Spring Boot application.
For now run java -jar 32-jdbc-autoconfig-5.3.23.jar, you should get the same output as before.
We overrode Spring Boot's default behavior and defined a DataSource for ourselves. But which approach more
appropriate?
Think about imperative declaration of DataSource auto- configuration disablement, versus disabling via configura
• If your use case is similar to wiring multiple data sources, it makes more sense to programmatically disable th
auto- configuration given this is an fixed aspect of your design.
• If your design style favors non-functional concerns in configuration then Spring Boot external configuration is a
available option.
# Summary
You should surmise by the end of the lab that Spring Boot can save you work:
Summary Instructors
In this lab you took the concepts you learned in this module and apply them to your Spring
Application.
Give Feedback
Help us improve by sharing your thoughts.
Give Feedback
Copyright © 2005-2024 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.