Spring is the framework for building enterprise-level Java applications. Spring Boot is built on top of Spring to simplify development by automating configuration and deployment (using embedded Tomcat/Jetty)

  • Spring Boot Doc: https://docs.spring.io/spring-boot/index.html
  • Bean : same as a component
  • Dependency Injection (DI) : process of wiring beans together like how component A depends on result of component B
  • Spring Application Context : the container that create and maintain components and inject them into beans as needed
  • Controller : responsible for fetching and processing data
  • Model : object responsible for ferrying data between a controller and the view responsible for rendering it
  • View : responsible for rendering data into HTML

Bean and @Autowired

Beans are classes that have been labeled @Component, @Service, @Repository, @Controller, or etc.

  • Spring will automatically create and manage those classes/beans on startup unless specified otherwise
  • For any bean that needs another bean, use @Autowired annotation to inject the needed bean
    • Reduces code to create and manage classes
    • @Autowired: can be omitted if there is only one constructor
    @Service
    public class UserService { } // Spring will create a new UserService() bean at startup
    ----------------------------------------------------------------------------
    @Service
    public class OrderService { // Spring will create a new OrderService(UserService) bean at startup
        private final UserService userService;
    
        @Autowired
        public OrderService(UserService userService) { // The required userService bean will be injected from what Spring created at startup 
            this.userService = userService;
        }
    }

Setup

Starting New Project

  1. In VS Code command palette type: Spring Initializr: create Maven project or Spring Initializr: create Gradle project
  2. Pick Spring Boot version
  3. Pick programming language
  4. Put in group id : identifier for organization or group in reverse domain name notation
    • Examples: com.google or io.github.tuan
  5. Put in artifact id : name of your project or module (Ex: taco-cloud)
  6. Pick package type: .jar or .war files
  7. Pick Java version
  8. Add dependencies

Testing Project

  • To run the test classes on the app, use ./mvnw test in the command line
  • ./mvnw clean test -X to get rid of leftover class files or incomptible versions from previous build
    • -X is for debug mode

Running Project

  • To run the app, use ./mvnw spring-boot:run in the command line
  • Can also use the Spring Boot Dashboard to start and run test by clicking the play and globe icons
  • Normally runs on http://localhost:8080/

Building Project

  • The app will be run from an executable .jar file
  • In the command line, use ./mvnw package to build the app into the target/ folder
  • In the command line, use java -jar target/{appName}.jar to run the .jar file

Deploying Project

Ch 18 of Spring in Action (Walls, C.)


Dependencies

Core Dependencies

  • Spring Boot Starter Web : adds REST API support using Spring MVC
    • Build controllers, handle HTTP requests/responses
  • Spring Boot Starter Test : includes JUnit, Mockito, and Spring Test
    • For unit and integration testing
  • Spring Boot Starter Validation/ Validation I/O : adds bean validation (JSR-380); spring-boot-starter-validation
    • Replace a bunch of if-else or switch-case statements to validate data
    • @NotNull : field annotation to make sure the field is not empty or null
    • @NotBlank : field annotation to make sure the field is not empty
    • @Size(min=1, message="You must select at least 1 ingredient") : field annotation to make sure the field is at least 1 in length and display the message if not
    • @Pattern(regexp="", message="") : field annotation to make sure the field matches the pattern
    • @Digits(integer=3, fraction=0, message="") : field annotation to make sure the field has 3 digits and is a whole number
    • @CreditCardNumber(message="") field annotation to make sure it's a valid credit card number using Luhn algorithm check
    • Validate request data using @Valid in the controller method parameter
    • @Data
      public class TacoOrder {
      
          @NotBlank(message = "Name is required")
          private String deliveryName;
      }
      --------------------------------
      
      @PostMapping
      public String processOrder(@Valid TacoOrder order, Errors errors, SessionStatus sessionStatus) {
  • Lombok : reduces boilerplate (getters, setters, constructors)
    • Site: https://projectlombok.org/
    • Lombok must be installed into IDE or else it will complain about missing getters/setters and methods
      • Comes with the Extension Pack for Java extension in VS Code
    • Automatically generate getter/setter methods as well as equals(), hashCode(), toString(), etc
    • @Data CLASS annotation: composite annotations for @Getter on all fields, @Setter on all non-final fields, @ToString, @EqualsAndHashCode, and @RequiredArgsConstructor
    • @Getter field annotation: automatically creates a getter method for the field
    • @Setter field annotation: automatically creates a getter method for the field
    • @ToString class annotation: automatically create a toString() method that has a format to include class name, field names and values; configurable
    • @EqualsAndHashCode class annotation: equals() and hashCode() method
      • By default, uses all non-static, and non-transient fields, but configurable
    • @RequiredArgsConstructor class annotation: automatically generates a constructor with one parameter for each field that is... final, but not initialized or that is annotated with @NonNull
  • Spring Boot DevTools : enables auto-reload during development
    • Automatically restarts your app when code changes; mainly code in src/main/ path
      • Does NOT automatically restart when dependencies change
    • Automatic browser refresh when browser-destined resources (such as templates, JS, stylesheets, and so on) change
      • Requires a LiveReload plugin in the browsers to work (available in Chrome, Safari, and Firefox)
    • Automatic disabling of template caches
    • Built in H2 Console, if the H2 database is in use

Database & Persistence Dependencies

  • Spring Boot Starter Data JPA : simplifies database access using JPA and Hibernate
    • For working with SQL databases using @Entity, @Repository
  • Spring Boot Starter JDBC : enables low-level database access with JDBC
    • Use for direct SQL execution or legacy DB connections
  • Spring Boot Starter Data MongoDB : provides integration with MongoDB
    • Use when working with NoSQL databases
  • H2 Database : lightweight in-memory database
    • Perfect for development and testing without external DB setup
  • MySQL/PostgreSQL Driver : adds database driver support
    • Used to connect your Spring Boot app to a relational database
  • Spring Data Solr : enables integration with Apache Solr search platform
    • Used to connect your Spring Boot app to a Solr server

Security & Authentication Dependencies

  • Spring Boot Starter Security : adds authentication and authorization features
    • Secure your routes, add login, and password encoding
  • Spring Security OAuth2 Resource Server : supports OAuth2 and JWT authentication
    • For token-based security in APIs
  • Spring Security JWT : manages JSON Web Tokens
    • Used for stateless authentication in REST APIs

API Communication & Serialization

  • Spring Boot Starter WebFlux : supports reactive, non-blocking REST APIs
    • Use for async or high-concurrency applications
  • Jackson Databind : handles JSON serialization and deserialization
    • Automatically included in spring-boot-starter-web
  • Spring Boot Starter WebClient : allows REST calls to external APIs
    • Modern alternative to RestTemplate

Utility & Tooling Dependencies

  • Spring Boot Actuator : exposes health and metrics endpoints
    • Monitor and manage your application at runtime
  • MapStruct : helps map between objects (e.g., DTOs ↔ Entities)
    • Used for clean data transfer between layers
  • ModelMapper : alternative object-mapping library
    • Automatically converts between DTOs and entities

Cloud, Messaging, & Advanced Features

  • Spring Boot Starter Data Redis : integrates with Redis for caching and data storage
    • Use for improving performance or distributed caching
  • Spring Boot Starter AMQP : supports message queues like RabbitMQ
    • Use for asynchronous communication between services
  • Spring Cloud : provides tools for microservices and distributed systems
    • Useful for service discovery, configuration, and resilience
  • Spring Boot Starter Mail : allows sending emails from your application
    • Use for notifications, password resets, etc.

Project Structre

  • mvnw and mvnw.cmd : Maven wrapper scripts to build the project even if Maven is not installed on the computer
  • Build config file: pom.xml for Maven or build.gradle for Gradle
    • Spring Boot version
    • Properties
    • Dependencies
    • Plugins
  • src/main/java/ : Java source code
    • /groupId/artifactId/projectNameApplication.java : Spring Boot main class that bootstraps the project
      • Where main app starts and contains config for Spring Framework or the config can be placed in a separate configuration class using annotation @Configuration
  • src/test/java/ : test source code
    • /groupId/artifactId/projectNameApplicationTests.java : simple test class to ensure Spring app context loads successfully
  • src/main/resources/ : static resources and config files (like application.properties)
    • /static/ : static content (images, stylesheets, JS)
    • /templates/ : template files to render content to browser
    • /application.properties : config properties for the app and dependencies
        spring.application.name=taco-cloud : set the name of the app
  • target/ or build : compiled output (auto-generated)

Spring Core

  • @Component : class annotation to mark the class as a Spring-managed bean so that it can be injected later through @Autowired
    • A Spring-bean/component is an objectcreated by the Spring container that manages its lifecycle and can inject it anywhere you need
    • A Spring-bean/component is a singleton object so there is one shared instance of it per Spring app context
      • Spring bean/componnent can implement interfaces
      • Be proxied (for transactions, caching, AOP, etc.)
      • Be replaced or mocked for testing
  • @Autowired : field annotation to tell Spring to find a bean/component of this type and inject it here
  • Converter interface : interface to convert a value to another value by implementing its convert() method
  • @Component
    public class IngredientByIdConverter implements Converter<String, Ingredient> {  
    
    private Map<String, Ingredient> ingredientMap = new HashMap<>();
      
      public IngredientByIdConverter() {
        ingredientMap.put("FLTO", 
            new Ingredient("FLTO", "Flour Tortilla", Type.WRAP));
        ingredientMap.put("COTO", 
            new Ingredient("COTO", "Corn Tortilla", Type.WRAP));
      }
    
    @Override
      public Ingredient convert(String id) {
        return ingredientMap.get(id);
      }
    }

Spring MVC Module

For building web applications; whether to return view (HTML) or data (for REST API - Ch 7 of Spring in Action)

App

  • @Controller : handles incoming HTTP requests, processing them, and returning a view/JSP
  • @RestController : handles incoming HTTP requests, processing them, and returning data (JSON/XML) directly
  • @GetMapping("/") : method annotation that indicates that if an HTTP GET request is received for the root path "/" then the annotated method should handle that request
  • @RequestMapping("/") : class annotation that indicates that if an HTTP GET request is received for the root path "/" then the annotated class should handle that request through the class that is annnoated with any of the following
    • @GetMapping : method annotation for method that handles HTTP GET requests
    • @PostMapping : method annotation for method that handles HTTP POST requests
    • @PutMapping : method annotation for method that handles HTTP PUT requests
    • @DeleteMapping : method annotation for method that handles HTTP DELETE requests
    • @PatchMapping : method annotation for method that handles HTTP PATCH requests
  • @SessionAttribute("modalName") : class attribute for Spring controllers to make sure Spring store the "modelName" so it persists across multiple requests
    • Used with @ModelAttribute(name = "modelName"); method annotation that specifies the return object of this method will be labelled "modelName" and put into the model
    • @Controller
      @SessionAttributes("tacoOrder")  // 👈 Keeps "tacoOrder" in session so it can span several pages/requests
      public class TacoOrderController {
      
          @ModelAttribute("tacoOrder")
          public Order order() {
              return new Order();
          }

Testing

  • @WebMvcTest : annotates test class to run in the context of a Spring MVC app
  • @Test : annotates test methods to be run
  • @Autowired : to inject the class with a MockMVC object to drive the mockup
  • @WebMvcTest(HomeController.class)                
    public class HomeControllerTest {
     
      @Autowired
      private MockMvc mockMvc;                       
      
      @Test
      public void testHomePage() throws Exception {
        mockMvc.perform(get("/"))                    
          .andExpect(status().isOk())                
          .andExpect(view().name("home"))            
          .andExpect(content().string(               
              containsString("Welcome to...")));
      }
    }

Spring Data

CRUD: create, read, update, and delete

  • CrudRepository provides basic CRUD operations for your entities so there is no need to implement their methods
  • CrudRepository<Entity, ID>:
    • Entity: parameter that tells which entity/table the CRUD operation are for
    • ID: parameter for the type of the primary key (ID field)
    • Usage: public interface IngredientRepository extends CrudRepository<Order, Long> {}
  • Built-In Methods
    • save(S entity) : insert or update an entity
    • findById(ID id) : retrieve an entity by its ID
    • findAll() : retrieve all entities
    • deleteById(ID id) : delete an entity by its ID
    • deleteAll() : delete all entities
    • count() : count the total number of entities
  • Customizing Methods: Spring Data can also create custom methods by parsing the method name
    • List<Order> findByDeliverZip(String deliveryZip) : return all entities by matching the deliveryZip property

JDBC

Low-level framework for interacting with SQL database where you write the SQL queries yourself

JPA

High-level framework for SQL where SQL is generated automatically from entity mappings

  • @Entity : class annotation for the object that will get mapped directly to a table in database
  • @Id : field annotation to designate it as the uniquely identify in the database; the primary key
    • @GeneratedValue(strategy = GenerationType.AUTO) : field annotation to let the database auto-generate the value for this field
  • Relationship Annotation
    • @ManyToMany : field annotation to designate a many-to-many relationship between two entities
    • @ManyToOne : field annotation to designate a many-to-one relationship between two entities
    • @OneToMany : field annotation to designate a one-to-many relationship between two entities
    • @OneToOne : field annotation to designate a one-to-one relationship between two entities
    • Cascade Type: Example: @ManyToMany(cascade = CascadeType.ALL)
      • CascadeType.ALL : apply all cascade operations to the related child entities
      • CascadeType.PERSIST : when the parent entity is saved, also save the related child entities
      • CascadeType.MERGE : when the parent entity is updated, also update the related child entities
      • CascadeType.REMOVE : when the parent entity is deleted, also delete the related child entities

Spring Security

Ch 5 and 12 of Spring in Action