# 01.3-SpringBoot basics-Lesson3: Spring Boot Basics for Web Development ###### tags: `Udacity` [ToC] {%youtube q84URC4H6YM%} >Spring Boot's Building Blocks ![](https://video.udacity-data.com/topher/2020/June/5ed93efc_l2-03-lesson-outline/l2-03-lesson-outline.png) **Lesson Outline** * Spring IoC Configuration: We discuss the basic mechanism at the core of Spring, Inversion of Control, and how to configure it for our applications. * Spring Components and Services: We introduce a mental model for developing with Spring, built around classes that we define called components and services. * Server-Wide Configuration: We learn how to configure certain server-wide properties of a Spring Boot application. * XML-Based Configuration: We discuss an older form of Spring configuration, still in use, that uses XML files to define dependencies, server-wide options, and more. # 02 Big Picture {%youtube nC57a-Gjm10%} >The Spring Transformation ![](https://i.imgur.com/RUk6PYJ.png) Of all the tools we'll be using in this course, Spring is the most important because it defines our entire style of application development. Spring is a framework for Inversion of Control, which means that to use it, we have to package our code into individual component classes, telling Spring which components need each other to function. Spring takes the component classes we define and the dependencies we define between them and instantiates a system of matching Java objects with references to each other. This frees us from having to write so-called "glue code" to instantiate, connect, and manage components manually, and allows us to instead focus on writing so-called business logic, or code that concerns itself exclusively on the conceptual model of the application. **Key Terms** * Inversion of Control (IoC): A design pattern in which the developer creates independent application components and uses a framework to connect them, rather than writing the integration code themselves * Business Logic: Code that relates exclusively to an application's conceptual model and featureset. Contrast with utility code like database access, HTTP request parsing, etc. * Persistent Components: Java Objects that Spring maintains over time; they're persistent because they're created and maintained for as long as the application needs them to be. * Dependency Injection: A mechanism by which IoC may be implemented. Components are configured with dependencies on other components, which are injected at runtime. Injection is quite literal - a component's dependencies are usually expressed as annotated fields on the component class, and Spring will populate those fields with the dependencies at runtime. # 03 Intuition Develop Your Intuition about Spring {%youtube qJV8KRC9Xhc%} [The code snippets for this lecture can be found here.](https://github.com/resisttheurge/udacity-jwdnd-c1-snippets/tree/master/src/main/java/com/udacity/jwdnd/c1/snippets/l2) When designing Spring applications, the most important principle to keep in mind is separation of concerns. What that really means is that for every problem your application has to solve has a home in a component class that is easy to find and flexible to use. By building your application out of small but focused components, you'll make the most of Spring's boilerplate-crushing power, and when it's time to add new features, you'll know exactly where to put them. On a larger team, this means greater coordination and less time spent trying to find and eliminate redundancies and conflicts. But in order to allow your components to communicate effectively with one another, you'll need a system of data types to share between them. These are simple classes designed to store structured data, and little else. They're useful as conceptual representations of application data, like user profiles, or shipment invoice details, but made to be used and manipulated by the components of an application. A good rule of thumb to decide which is which is the new keyword test. A component should never be manually instantiated with the new keyword - components are managed by Spring, which means we need to rely on dependency injection to get a component reference. Data types, on the other hand, are no more special than Java's collections, and we can manually instantiate them with the new keyword whenever we'd like. Of course, we can use Spring (and its related libraries) to instantiate them for us as well, and in the coming lessons we sometimes will. **Key Terms:** * Separation of Concerns: A code organization philosophy that emphasizes single-purpose components. In Java and Spring, this means keeping all methods related to a specific problem domain in the same class, for the sake of maintainability and reducing code reuse. * Data Types: Sometimes called POJOs (plain-old-java-objects), Data Types are classes in application designed purely to hold structured application data, like users, profiles, or anything else an application might manage. These objects are helpful for us to maintain a good conceptual model of an application, and are created and accessed frequently during execution. * Components: Components are persistent class instances managed by Spring in an application. They usually resemble libraries more than typical objects, with methods that must be called to perform specific actions. Components are only created when Spring is configured to create them, usually at server startup. # 04 Spring Boot IoC Configuration {%youtube QjtzCdGnV9Y%} Under the hood, Spring is just a Java application itself - and it responds to our configuration in a predictable way. When a Spring application starts, it scans your code base for specially-marked class files and configuration options. It uses that information to instantiate your application components as Java objects, and it stores them in a special data structure called the application context. This context is ultimately very similar to a Map or a python dictionary, and it can be queried at runtime to find specific components when needed. This is a closed system, so components instantiated outside of Spring won't automatically be injected with dependencies like those instantiated by Spring. Mind the `new` keyword! {%youtube xo9OIgvQtMA%} [You can find the lecture sample code here](https://github.com/udacity/nd035-c1-spring-boot-basics-examples/tree/master/udacity-jwdnd-c1-l2-spring-ioc-config-master) In a Spring Boot application, the basic setup of the Spring application context has already been done for us. In a generated project starter, you're always given a main application class with the `@SpringBootApplication` annotation. This annotation is actually equivalent to three other annotations from Spring: `@Configuration`, `@EnableAutoConfiguration` and `@ComponentScan`. `@Configuration` tells Spring that the annotated class includes component definitions for Spring to process. These take the form of `@Bean`-annotated method whose return values are included as components in the application context. These methods can also take parameters, which act like the dependencies of the components returned by the methods. The `@EnableAutoConfiguration` annotation tells Spring that it's okay to try to match dependencies to components automatically. Usually that means dependencies are filled based on type, so in the example above, we have the `compoundMessage` method which depdends on the `basicMessage` implicitly - the only String bean that Spring is aware of when constructing the `compoundMessage` is the `basicMessage`, so it uses that. When there are multiple beans that satisfy a specific dependency, Spring's auto configuration needs some help to decide which to use. A common solution is to mark a bean with the `@Primary` annotation to indicate a universally-preferred bean for its type. Or, you can use pairs of `@Qualifier` annotations on beans and the dependencies that references them to gain a finer level of control. `@ComponentScan` provides another layer of automation - automatic component scanning throughout your entire code base. But that's a topic for the next video! > How Spring Processes an IoC Configuration ![](https://i.imgur.com/pmodYAN.png) **Key Terms** * Configuration Files: Project files that configure some part of Spring's operation. Some are embedded in Java classes, like we just discussed, and others are `.properties`, `.yaml`, and `.xml` files that we'll discuss later this lesson. Some of them configure the IoC context, like the ones we just discussed, and others configure more abstract pieces of Spring's system. * Component Annotations: Component annotations are annotations that identify application components for Spring to manage. `@Bean` and `@Configuration` are examples from the most recent videos, and in the next section we'll discuss `@Component` and `@Service` as well. * Application Context: Spring's application context is just a giant data structure that holds all application component instances. It can be queried to gain access to a specified component at runtime, and it's what Spring uses to resolve dependencies. * Beans: "Beans" are Spring's name for generic application components, and include any value Spring has stored in the application context. A bean is always either an object or primitive value. * Closed System: Spring's application context is a closed system, which means that it manages all of the components stored within. It is not possible to instantiate a component manually and still link it fully with Spring - it will never be aware of the components inside of Spring's application context, and vice versa. * `@SpringBootApplication`: An annotation put on the main application class of a Spring Boot project. It serves as an alias of three other annotations, `@Configuration`, `@EnableAutoConfiguration`, and `@ComponentScan` * `@Configuration`: A class annotated with `@Configuration` is instantiated and managed by Spring as a component, but also as a bean factory. Any methods of the configuration class that are annotated with `@Bean` are used by Spring to create new beans to add to the application context. * `@Bean`: A method annotated with `@Bean` inside of a configuration class will be used by Spring to generate a bean of the method's return type. This means that the developer can manually configure beans to be included in the application context. * `@EnableAutoConfiguration`: A class annotated with `@EnableAutoConfiguration` tells Spring to try to automatically match beans to dependencies based primarily on type. This reduces the need for boilerplate code explicitly identifying individual beans as dependencies. * `@Primary`: This annotation distinguishes the annotated bean method as the default dependency of its type. This is used to resolve conflicts that arise from having multiple bean definitions of the same type when auto configuration is enabled. * `@Qualifier:` This annotation distinguishes the annotated bean method or dependency declaration as a qualified bean or dependency. Qualified beans are considered for unqualified dependencies, but only matching qualified beans are considered for qualified dependencies. You can read more about it [here](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-autowired-annotation-qualifiers). **Further Research** * [Official Spring IoC Documentation](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans) * [Official Spring Annotation-Based Configuration Documentation](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-annotation-config) # 05 Components and Services {%youtube s9R8zH5M-eY%} If we want to declare custom classes as Spring Components, the best way to do it is to make use of `@ComponentScan`, an annotation that tells Spring to search your code base for classes annotated with `@Component`. These classes will automatically be instantiated as Spring beans, so there's no need to define an `@Bean`-annotated method if you already have `@Component` on you classes. There are other variants of `@Component` that identify specific roles for each component to play. We'll see some examples of these in the coming lectures, but if you want to learn more, check out the link below. One important thing to keep in mind is that `@ComponentScan` only marks the package of the class it's annotating for scanning - any classes outside of that package or its subpackages will be excluded by Spring. Here are the [official Spring docs for](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ComponentScan.html) `@ComponentScan` as well as the [official Spring docs explaining the how different stereotype annotations like `@Component`, `@Service`, `@Repository`, and others, function.](https://docs.spring.io/spring/docs/4.3.27.RELEASE/spring-framework-reference/htmlsingle/#beans-stereotype-annotations) ![](https://i.imgur.com/6ASFu2r.png) **Key Terms** * Onion Architecture: An architectural pattern in which an application is separated into nested layers. In order for a request to be processed by the application, it must first travel through an outer layer of external interfaces and controllers, then through a middle layer of services and business logic, and finally through a persistence layer of data access objects. The separation of these layers emphasizes clean separation of concerns. * Application Component: In Spring, this is any @Component-annotated class that is instantiated by Spring and placed in Spring's application context. Architecturally speaking, this is a logical unit of an application - a single-purpose library or object that solves a particular problem an application faces. * Service: In Spring, this is any `@Service`-annotated class, handled identically to an `@Component`-annotated class. The difference between the two is semantics - a component is the most generic type of bean, and can be any kind of shared application structure. A service is specifically a collection of library methods that manage one aspect of an application's business logic. For example, a `UserService` would expose high-level actions related to the users of an application, and an `AuthenticationService` would expose actions for registering and authenticating a user. Services represent the middle layer of an onion architecture, and should contain the bulk of an application's business logic. * Repository: In Spring, an `@Repository`-annotated class is treated identically to an `@Component`-annotated one, but as with `@Service`, the semantics are different. In an onion architecture, repositories are the inner layer - each repository should act like an interface to a specific set of stored or persistent data. For example, a `UserRepository` would expose an interface capable of create/read/update/delete and query operations on the `users` table of the database. # 07 Exervise: Components and Services **Exercise: Components and Services** This exercise presents you with a miniature project whose Java classes depend on each other to get some work done. However, none of the classes have the Spring annotations we discussed in this lesson! Your job is to figure out which classes need the various component annotations. You’ll also need to add an annotation so that Spring will perform the component scan that it can use to find the components and create Beans for them. All of the files you need to edit are already open for you. Remember that not all classes need annotations, only the ones that rely on accessing another object instance without creating it themselves. However, don’t forget that Spring needs to create instances of classes itself to handle web requests, too! Please note that you cannot build this project in a Udacity workspace. You can build it locally if you download the `l2e1` folder. You can download it by right-clicking or two-finger clicking on the `l2e1` folder and pressing "Download". You don't need to submit your final solution. # 08 Solution: Components and Services {%youtube Xxtlhczz1w0%} There are quite a few classes in this example, but only some of them need annotations. WE can figure out which ones by following the chain of dependencies - `FoodController` references `FoodService` which references `FoodRepository`, which means all of them need some variation of `@Component` on each. Yes, even `FoodController` at the top of the chain - remember that in order for Spring fill dependencies, all related components must be configured for IoC. We also need to annotate our main application class with `@SpringBootApplication`. Remember that this is what configures Spring's component scanning and auto-configuration, so without this, the `@Component` variants we used above wouldn't be seen by Spring. > Course1ExercisesApplication.java ```java /** * Controller for receiving requests. * This class needs to be a Spring Component so that Spring can * automatically create instances of it to receive web requests. We use * the @Controller annotation variation of @Component for this purpose. */ @Controller @RequestMapping("/food") public class FoodController { private FoodService foodService; public FoodController(FoodService foodService) { this.foodService = foodService; } @GetMapping public String getHomePage(FoodForm foodForm, Model model) { foodService.addFood(foodForm.getFoodName(), foodForm.getCalories(), foodForm.getMealTime()); return "foodAdded"; } } ``` > FoodService.java ```java /** * Food Service that performs business logic operations regarding food * This class needs to be a component, because our Controller has a reference to * it that it doesn't create itself. Marking this as a @Service lets Spring know * to make instances of this bean available to other classes, though @Component would work as well. */ @Service public class FoodService { private FoodRepository foodRepository; public FoodService(FoodRepository foodRepository) { this.foodRepository = foodRepository; } public Boolean isFoodAvailableAtMealTime(String foodName, MealTime mealTime) { return foodRepository.getFood(mealTime).stream() .filter(food -> food.getName().equals(foodName)) .findFirst() .isPresent(); } public void addFood(String foodName, Integer calories, MealTime mealTime) { foodRepository.addFood(mealTime, new FoodData(foodName, calories)); } public FoodRepository getFoodRepository() { return foodRepository; } public void setFoodRepository(FoodRepository foodRepository) { this.foodRepository = foodRepository; } } ``` > FoodRepository.java ```java /** * Pretend repository implementation * This class needs to be a Spring component as well, because our FoodService relies on it. We use * the @Repository annotation here to denote its function, but for this example @Component would work just * fine as well. */ @Repository public class FoodRepository { private Map<MealTime, List<FoodData>> foodDatabase = new EnumMap<>(MealTime.class); public List<FoodData> getFood(MealTime mealTime) { return foodDatabase.getOrDefault(mealTime, new ArrayList<>()); } public void addFood(MealTime mealTime, FoodData food) { foodDatabase.getOrDefault(mealTime, new ArrayList<>()).add(food); } } ``` # 09 Server-Wide Configuration {%youtube bDj3gJpQ5Uw%} [The lecture code example can be found here.](https://github.com/udacity/nd035-c1-spring-boot-basics-examples/tree/master/udacity-jwdnd-c1-l2-server-config-masterg) Spring Boot does a lot to simplify the setup of a new Spring application, but sometimes, you need to change how it works. That's what the `application.properties` file is for! You can find it in the `src/main/resources` folder of a generated Spring Boot project, and it allows you to configure anything from the server's hostname and port to the size and colors of the Spring logo that appears in the console when starting an application. [You can find reference documentation for all of the available config options here.](https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html) **Key Terms** * Properties File: A file with the `.properties` extension that consists of plain-text `key=value` pairs separated by new lines. This format is often used by Java libraries and frameworks because it provides a simple way to specify named constants in a plain text file. # 10 Exervice: Server-Wide Configuration Exercise: Server-Wide Configuration For this example, you’ll be given an application.properties file that matches what you see when you create a new project. That means it’ll be totally blank! **Update the application.properties file to meet the needs of your application as described here: ** * Make sure the server uses port `8086` instead of the default * Set the log level for the `com.udacity.jdnd.course1exercises` package to DEBUG * Set the username and password for the primary data source to values of your choice * Enable template caching for Thymeleaf * Enable remote restart through devtools Remember that you can find all these properties in the [Spring Common Application properties documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html), but IntelliJ will also auto-complete many properties for you, so you can often add properties without a reference when working in your IDE. # 11 Solution: Servier-Wide Configuration Solution: Server-Wide Configuration > application.properies ```java server.port=8086 logging.level.com.udacity.jdnd.course1exercises=DEBUG spring.datasource.username=superman spring.datasource.password=FishTacos1234 spring.thymeleaf.cache=true spring.devtools.remote.restart.enabled=true ``` Hopefully you were able to find all these without too much trouble! Most of the time, your properties will be driven by specific goals you need to accomplish. You’ll want to be prepared to look them up like you did for this exercise. However, Spring’s intelligent defaults means that your application will often work fine with nothing in your properties file at all! That means we can usually rely on the defaults, and just be ready to look up the properties in the documentation when we need to. # 12 Edge Case: XML Configuration Edge Case: When You have to Use XML Configuration ![](https://i.imgur.com/4bKgYXy.png) ![](https://i.imgur.com/SfkOfUX.png) ![](https://i.imgur.com/sSD8FYu.png) ![](https://i.imgur.com/ktcps3C.png) ![](https://i.imgur.com/vPv5Zyz.png) {%youtube fWZ62Ik-rAk%} [You can find the beans.xml sample code from the lecture here.](https://github.com/udacity/nd035-c1-spring-boot-basics-examples/blob/master/udacity-jwdnd-c1-snippets-master/src/main/resources/l2/beans.xml) Spring's annotation-based configuration is really convenient and allows us to see directly in our Java code how Spring is configured. This is a new API, though, and Spring's original configuration format was through XML. We won't be using this older format in the course, but it's important to be aware of because it's still supported by Spring, and many older projects still use it. The key thing to remember is that Spring's annotation- and XML-based configuration systems are both equally capable of configuring Spring, so if you ever find yourself in a situation where you need one but only know how to do it in the other, you can always find a way to translate between them. **Key Terms** * Legacy: In a programming context, legacy usually refers to older code that still functions or is expected to function, but is on the verge of being made obsolete by newer technologies. A legacy application is one that is no longer being actively built upon, and is instead in maintenance mode. * XML: eXtensible Markup Language. This is a flexible data format that allows for extension, as the name suggests. Many applications and libraries use XML as a way to store structured application data out of memory, and it's also a popular data interchange format on the web. **Further Research** [Here are the official Spring docs for annotation-based configuration, which feature a discussion of XML vs. annotations and many examples of how the two relate to each other.](https://docs.spring.io/spring/docs/4.3.27.RELEASE/spring-framework-reference/htmlsingle/#beans-annotation-config) # 13 Final Review Exercise: Final Review This is a continuation of your previous Final Review exercise. You will not be using a Udacity workspace to complete this, and you will be building this locally on your machine. ![](https://i.imgur.com/TFqOZKC.png) # 15 Solution: Final Review {%youtube 20KMZjwtIWg%} [My solution code for this final review can be found here.](https://github.com/udacity/nd035-c1-spring-boot-basics-examples/tree/master/udacity-jwdnd-c1-l2-final-review-solution-master) **Glossary** * Inversion of Control (IoC): A design pattern in which the developer creates independent application components and uses a framework to connect them, rather than writing the integration code themselves * Business Logic: Code that relates exclusively to an application's conceptual model and featureset. Contrast with utility code like database access, HTTP request parsing, etc. * Persistent Components: Java Objects that Spring maintains over time; they're persistent because they're created and maintained for as long as the application needs them to be. * Dependency Injection: A mechanism by which IoC may be implemented. Components are configured with dependencies on other components, which are injected at runtime. Injection is quite literal - a component's dependencies are usually expressed as annotated fields on the component class, and Spring will populate those fields with the dependencies at runtime. * Separation of Concerns: A code organization philosophy that emphasizes single-purpose components. In Java and Spring, this means keeping all methods related to a specific problem domain in the same class, for the sake of maintainability and reducing code reuse. * Data Types: Sometimes called POJOs (plain-old-java-objects), Data Types are classes in application designed purely to hold structured application data, like users, profiles, or anything else an application might manage. These objects are helpful for us to maintain a good conceptual model of an application, and are created and accessed frequently during execution. * Components: Components are persistent class instances managed by Spring in an application. They usually resemble libraries more than typical objects, with methods that must be called to perform specific actions. Components are only created when Spring is configured to create them, usually at server startup. * Configuration Files: Project files that configure some part of Spring's operation. Some are embedded in Java classes, like we just discussed, and others are .properties, .yaml, and .xml files that we'll discuss later this lesson. Some of them configure the IoC context, like the ones we just discussed, and others configure more abstract pieces of Spring's system. * Component Annotations: Component annotations are annotations that identify application components for Spring to manage. @Bean and @Configuration are examples from the most recent videos, and in the next section we'll discuss @Component and @Service as well. * Application Context: Spring's application context is just a giant data structure that holds all application component instances. It can be queried to gain access to a specified component at runtime, and it's what Spring uses to resolve dependencies. * Beans: "Beans" are Spring's name for generic application components, and include any value Spring has stored in the application context. A bean is always either an object or primitive value. * Closed System: Spring's application context is a closed system, which means that it manages all of the components stored within. It is not possible to instantiate a component manually and still link it fully with Spring - it will never be aware of the components inside of Spring's application context, and vice versa. * @SpringBootApplication: An annotation put on the main application class of a Spring Boot project. It serves as an alias of three other annotations, @Configuration, @EnableAutoConfiguration, and @ComponentScan * @Configuration: A class annotated with @Configuration is instantiated and managed by Spring as a component, but also as a bean factory. Any methods of the configuration class that are annotated with @Bean are used by Spring to create new beans to add to the application context. * @Bean: A method annotated with @Bean inside of a configuration class will be used by Spring to generate a bean of the method's return type. This means that the developer can manually configure beans to be included in the application context. * @EnableAutoConfiguration: A class annotated with @EnableAutoConfiguration tells Spring to try to automatically match beans to dependencies based primarily on type. This reduces the need for boilerplate code explicitly identifying individual beans as dependencies. * @Primary: This annotation distinguishes the annotated bean method as the default dependency of its type. This is used to resolve conflicts that arise from having multiple bean definitions of the same type when auto configuration is enabled. * @Qualifier: This annotation distinguishes the annotated bean method or dependency declaration as a qualified bean or dependency. Qualified beans are considered for unqualified dependencies, but only matching qualified beans are considered for qualified dependencies. You can read more about it here. * Onion Architecture: An architectural pattern in which an application is separated into nested layers. In order for a request to be processed by the application, it must first travel through an outer layer of external interfaces and controllers, then through a middle layer of services and business logic, and finally through a persistence layer of data access objects. The separation of these layers emphasizes clean separation of concerns. * Application Component: In Spring, this is any @Component-annotated class that is instantiated by Spring and placed in Spring's application context. Architecturally speaking, this is a logical unit of an application - a single-purpose library or object that solves a particular problem an application faces. * Service: In Spring, this is any @Service-annotated class, handled identically to an @Component-annotated class. The difference between the two is semantics - a component is the most generic type of bean, and can be any kind of shared application structure. A service is specifically a collection of library methods that manage one aspect of an application's business logic. For example, a UserService would expose high-level actions related to the users of an application, and an AuthenticationService would expose actions for registering and authenticating a user. Services represent the middle layer of an onion architecture, and should contain the bulk of an application's business logic. * Repository: In Spring, an @Repository-annotated class is treated identically to an @Component-annotated one, but as with @Service, the semantics are different. In an onion architecture, repositories are the inner layer - each repository should act like an interface to a specific set of stored or persistent data. For example, a UserRepository would expose an interface capable of create/read/update/delete and query operations on the users table of the database. * Properties File: A file with the .properties extension that consists of plain-text key=value pairs separated by new lines. This format is often used by Java libraries and frameworks because it provides a simple way to specify named constants in a plain text file. * Legacy: In a programming context, legacy usually refers to older code that still functions or is expected to function, but is on the verge of being made obsolete by newer technologies. A legacy application is one that is no longer being actively built upon, and is instead in maintenance mode. * XML: eXtensible Markup Language. This is a flexible data format that allows for extension, as the name suggests. Many applications and libraries use XML as a way to store structured application data out of memory, and it's also a popular data interchange format on the web. # 15 Lesson Conclusion {%youtube s-EyLno-X78%} Congratulations, you've made it through one of the toughest lessons in this course! Working with Spring requires an entirely new mentality when it comes to application design, and we had a lot of ground to cover in this lesson to lay the foundations for the rest of the course. Next lesson, we'll be adding some real functionality to our applications by integrating Spring MVC and Thymeleaf to render web pages for our clients.