Spring Boot Backend Development Course, Creating the First Spring Boot 3 Example

Hello! In this blog post, we will develop our first web application using Spring Boot 3. Spring Boot is a framework that helps in easily creating web applications based on Java. It is designed to enhance efficiency and productivity, and is widely used by many developers. Through this process, we will build a simple RESTful API.

1. What is Spring Boot?

Spring Boot is a library built on top of the Spring Framework, providing an environment to create Spring applications quickly and easily. Spring Boot has the following advantages:

  • Auto-configuration: Spring Boot automatically handles the configuration of the application, reducing the complex setup process for developers.
  • Dependency Management: You can easily add and manage the necessary libraries through Maven or Gradle.
  • Standalone: Spring Boot applications are built as executable JAR files and do not require a separate web server.
  • Embedded Server Support: It supports embedded servers like Tomcat, Jetty, and Undertow for quick testing and deployment.

2. Preparing the Development Environment

The following environment is required to develop a Spring Boot application:

  • Java JDK 17 or higher: Spring Boot 3.x runs on Java 17 or higher. You need to install the JDK and set the environment variables.
  • IDE: Integrated Development Environments (IDE) such as IntelliJ IDEA or Eclipse are recommended. In this example, we will use IntelliJ IDEA.
  • Build Tool: You need to choose either Maven or Gradle to manage dependencies. We will use Maven in this example.

3. Creating the Project

There are several ways to create a Spring Boot project, but to save time, we’ll use Spring Initializr. Please follow the steps below:

  1. Open Spring Initializr in your web browser.
  2. Enter the following settings:
    • Project: Maven Project
    • Language: Java
    • Spring Boot: 3.x.x (latest version)
    • Project Metadata:
      • Group: com.example
      • Artifact: demo
      • Name: demo
      • Description: Demo project for Spring Boot
      • Package name: com.example.demo
      • Packaging: Jar
      • Java: 17
  3. Add the following dependencies:
    • Spring Web
    • Spring Data JPA
    • H2 Database
  4. Click the Generate button to download the ZIP file, then extract it.

4. Opening the Project in the IDE

After launching IntelliJ IDEA, open the project as follows:

  1. Click on the File menu and select “Open”.
  2. Select the extracted project folder and click the Open button.
  3. Select Gradle or Maven to download the necessary libraries.

5. Writing the Basic Application Code

After the basic structure of the project is created, the entry point of the application, DemoApplication.java, will be generated. The file looks like this:

package com.example.demo;

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

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Now, let’s add a controller class to create a REST API. Create a file named HelloController.java at the path src/main/java/com/example/demo.

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello, Spring Boot 3!";
    }
}

The code above is a simple controller that returns the string “Hello, Spring Boot 3!” when a GET request is sent to the “/hello” URL.

6. Running the Application

Now, let’s run the application. Click the run button in the top menu of IntelliJ IDEA, as shown below:

  • Run → Run ‘DemoApplication’

If the application starts successfully, “Started DemoApplication in …” message will be displayed in the console. Now open your web browser and access the URL http://localhost:8080/hello.

If it works correctly, you will see the message “Hello, Spring Boot 3!”.

7. Implementing Simple CRUD using H2 Database

Now, we will implement simple CRUD (Create, Read, Update, Delete) operations using H2 data. First, add the following content to the src/main/resources/application.properties file to set up the H2 database:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=create

Next, let’s create a model class. Create a file named Product.java at the path src/main/java/com/example/demo.

package com.example.demo;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

Now, we will create a service and controller to perform CRUD operations for the Product model. Create a file named ProductController.java at the path src/main/java/com/example/demo.

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/products")
public class ProductController {

    @Autowired
    private ProductRepository productRepository;

    @GetMapping
    public List getAllProducts() {
        return productRepository.findAll();
    }

    @PostMapping
    public Product createProduct(@RequestBody Product product) {
        return productRepository.save(product);
    }

    @GetMapping("/{id}")
    public ResponseEntity getProductById(@PathVariable Long id) {
        return productRepository.findById(id)
                .map(product -> ResponseEntity.ok().body(product))
                .orElse(ResponseEntity.notFound().build());
    }

    @PutMapping("/{id}")
    public ResponseEntity updateProduct(@PathVariable Long id, @RequestBody Product productDetails) {
        return productRepository.findById(id)
                .map(product -> {
                    product.setName(productDetails.getName());
                    product.setPrice(productDetails.getPrice());
                    Product updatedProduct = productRepository.save(product);
                    return ResponseEntity.ok().body(updatedProduct);
                }).orElse(ResponseEntity.notFound().build());
    }

    @DeleteMapping("/{id}")
    public ResponseEntity deleteProduct(@PathVariable Long id) {
        return productRepository.findById(id)
                .map(product -> {
                    productRepository.delete(product);
                    return ResponseEntity.noContent().build();
                }).orElse(ResponseEntity.notFound().build());
    }
}

Finally, create a ProductRepository interface to define methods to interact with the database. Create a file named ProductRepository.java at the path src/main/java/com/example/demo.

package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository {
}

8. Running and Testing the Application

Restart the application and use an API testing tool like Postman to test the CRUD API. Here are examples for each request:

  • Create Product:
  •     POST /products
        {
            "name": "Sample Product",
            "price": 19.99
        }
        
  • Get All Products:
  •     GET /products
        
  • Get Product by ID:
  •     GET /products/{id}
        
  • Update Product:
  •     PUT /products/{id}
        {
            "name": "Updated Product",
            "price": 29.99
        }
        
  • Delete Product:
  •     DELETE /products/{id}
        

9. Checking the H2 Console

You can also manage data through the H2 database. Open your web browser and go to http://localhost:8080/h2-console. Enter jdbc:h2:mem:testdb in the JDBC URL, use sa for the username, and click the Connect button.

Now you can perform various tasks such as querying or deleting data from the H2 database.

10. Conclusion and Next Steps

In this post, we implemented simple CRUD functionality using Spring Boot 3 and H2 database to create a RESTful API. I hope this example helped you understand the basic concepts and workings of Spring Boot. In the future, you can enhance the application by adding more complex databases and business logic.

In the next blog post, we will cover Spring Security for authentication and authorization. Thank you!

Spring Boot Backend Development Course, Inversion of Control and Dependency Injection

Author: [Author Name]

Date: [Date]

1. Introduction

Spring Boot is a framework that helps to quickly develop web applications based on Java. In this course, we will explore one of the core concepts of Spring Boot: Inversion of Control (IoC) and Dependency Injection (DI). These two concepts are crucial in determining how to design and maintain the structure of Spring Boot applications.

2. Inversion of Control (IoC)

Inversion of Control is a design pattern where the control flow of a program is managed by an external framework rather than by traditional means. In traditional object-oriented programming, objects create and interact with other objects on their own, but with IoC, the creation and lifecycle of objects are managed externally. This reduces the coupling of the system, allowing for more effective code management.

2.1 The Need for IoC

The main advantage of IoC lies in the weakening of the coupling between objects. This increases code reusability and testability while maximizing flexibility to changes. For example, managing dependencies between objects makes it much easier to replace a new object or modify an existing one.

2.2 Implementation of IoC

IoC can be implemented in various ways, but in Spring, it is primarily achieved through Dependency Injection (DI). DI is a method of receiving the necessary objects from the outside, transferring the responsibility of object creation and management to the Spring container. This allows us to design objects independently.

3. Dependency Injection (DI)

Dependency Injection is a form of IoC that creates objects by injecting dependencies from the outside. The Spring framework supports various ways to inject dependencies: constructor injection, setter injection, and field injection are examples.

3.1 Constructor Injection

Constructor injection is a way to pass dependencies as arguments to the object’s constructor. This is useful when dependencies are essential. For example:

                @Component
                public class UserService {
                    private final UserRepository userRepository;

                    @Autowired
                    public UserService(UserRepository userRepository) {
                        this.userRepository = userRepository;
                    }
                }
            

3.2 Setter Injection

Setter injection is a method of injecting dependencies through the setter methods of an object. This is useful when dependencies are optional:

                @Component
                public class UserService {
                    private UserRepository userRepository;

                    @Autowired
                    public void setUserRepository(UserRepository userRepository) {
                        this.userRepository = userRepository;
                    }
                }
            

3.3 Field Injection

Field injection is a method of directly injecting dependencies into the fields of a class, which makes the code concise but presents difficulties in testing:

                @Component
                public class UserService {
                    @Autowired
                    private UserRepository userRepository;
                }
            

4. IoC and DI in Spring Boot

Spring Boot provides various features to make application configuration easier. By default, Spring Boot automatically detects and manages classes marked with @Component, @Service, @Repository, etc., through component scanning.

4.1 @ComponentScan

Using the @ComponentScan annotation, all components within the specified package can be automatically discovered and configured. This eliminates the need to manually register beans.

4.2 @Configuration and @Bean

It is also possible to manage dependencies using the @Bean annotation in classes declared with the @Configuration annotation. This makes the implementation of the concept of Inversion of Control clearer:

                @Configuration
                public class AppConfig {
                    @Bean
                    public UserService userService() {
                        return new UserService(userRepository());
                    }

                    @Bean
                    public UserRepository userRepository() {
                        return new JpaUserRepository();
                    }
                }
            

5. Conclusion

Inversion of Control and Dependency Injection are core concepts in many modern frameworks, including Spring Boot. By understanding and leveraging these two concepts, we can write cleaner and more maintainable code. Now, you too can maximize the benefits of object-oriented design by actively utilizing IoC and DI when designing Spring Boot applications.

If you found this course helpful, please share it!

Spring Boot Backend Development Course, Properly Writing Test Code

Test code is essential in software development. Especially when developing large-scale applications, it is common to modify code or add new features. Each time this happens, it is difficult to be sure where the failure may occur, so it is important to write reliable test code. In this article, we will specifically look at how to write test code using Spring Boot.

1. What is Spring Boot?

Spring Boot is a platform for application development based on the Spring framework. It helps developers build and deploy applications easily without extensive setup. The main features of Spring Boot are as follows:

  • Auto-configuration
  • Standalone applications
  • Minimal configuration
  • Powerful module and dependency management

2. Why is test code necessary?

Test code is very important for improving the quality and maintainability of an application. With test code, we can:

  • Validate that the application’s functionality is working correctly.
  • Handle conditional logic and edge cases.
  • Ensure that existing features remain intact after code changes.
  • Manage dependencies between modules and quickly identify issues during integration testing.

3. Setting up test code in Spring Boot

The necessary library for writing test code in Spring Boot is `spring-boot-starter-test`. You set up the test environment by adding this library to `pom.xml`.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

Afterwards, you will create a test class using SpringJUnit4ClassRunner. Now, let’s look at several annotations that can be used in the test class.

3.1 @SpringBootTest

This annotation loads the context of the Spring Boot application, allowing for integration testing. All beans in the application are loaded, enabling testing of the entire application.

3.2 @MockBean

To efficiently test services connected to external APIs or databases, `@MockBean` can be used to mock the service. This helps strengthen the unit testing of the code.

3.3 @Autowired

This annotation allows for injection of required beans into the test class through Spring’s dependency injection. This makes it easy to validate the functionality of the class being tested.

4. Writing basic test code

Let’s first create a simple controller class.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello, World!";
    }
}

Now, let’s write the test code for the above controller.

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

@WebMvcTest(HelloController.class)
public class HelloControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void helloTest() throws Exception {
        mockMvc.perform(get("/hello"))
                .andExpect(content().string("Hello, World!"));
    }
}

In the above code, we use the `WebMvcTest` annotation to test the `HelloController`. We simulate an HTTP GET request using `MockMvc` and validate the result.

5. Testing the service layer

To write tests for the service layer, we will use the `@SpringBootTest` annotation and now check the internal logic of the service.

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void testUserCreation() {
        User user = new User("testUser");
        userService.createUser(user);

        User foundUser = userService.findUserByName("testUser");
        assertEquals("testUser", foundUser.getName());
    }
}

In service tests, we call the actual service methods to verify the expected results. This allows us to validate the business logic through the process of creating and retrieving data.

6. Refactoring test code

There is a lot of room for improvement in test code. We can reduce duplication by extracting repetitive code into methods. Additionally, we can write common code to execute before each test using the `@BeforeEach` annotation.

import org.junit.jupiter.api.BeforeEach;

public class UserServiceTest {
    
    @BeforeEach
    public void setup() {
        // Common execution code
    }
    
    @Test
    public void testUserCreation() {
        // Test code
    }
}

7. Integration testing and End-to-End testing

Integration testing validates the interaction between modules, checking whether multiple components work together. This generally includes interactions with databases and external APIs. End-to-End testing is the process of verifying that the application functions correctly from the user’s perspective.

In Spring Boot, we can efficiently test the web layer through MockMvc, and we can write integration test code that uses `@Autowired` for actual database integration testing.

8. Test coverage

Test coverage indicates how much of the code is being tested. A higher value indicates improved software quality. It is important to use tools like Jacoco to check test coverage and identify which code is excluded from testing.

9. Conclusion

Writing test code in Spring Boot is essential for increasing the reliability and maintainability of applications. We hope you utilize the various testing techniques introduced today to create reliable applications.

Testing is a crucial part of the development process and helps maintain integrity, especially in rapidly changing environments. Write proper test code to create high-quality software.

Spring Boot Backend Development Course, Check Operation

Spring Boot is a framework based on Java (Spring Framework) that helps developers quickly build applications. In this course, we will step-by-step explore how to start backend development using Spring Boot and explain how to verify that the developed application is functioning correctly.

1. What is Spring Boot?

Spring Boot is designed to simplify the complex setup and configuration of the existing Spring Framework, allowing developers to easily start projects. This increases productivity and helps developers quickly create microservices.

  • Autoconfiguration: Automatically applies basic configurations, so developers do not have to spend time on detailed settings.
  • Starter Dependencies: Provides starter packages that help easily add the basic dependencies needed to start a Spring Boot project.
  • Embedded Server: Supports embedded servers such as Tomcat and Jetty, allowing applications to run without separate server configuration.

2. Setting Up the Development Environment

2.1 Installing Required Tools

To start a Spring Boot project, you need JDK, an IDE, and Maven or Gradle. Here are the setup methods:

  • Install JDK: Install Oracle JDK or OpenJDK. JDK 11 or higher is required.
  • Install IDE: Download and install your preferred IDE such as IntelliJ IDEA, Eclipse, or STS.
  • Install Maven or Gradle: Install Maven or Gradle for dependency management. Using built-in support from the IDE is also recommended.

2.2 Creating a Project

You can easily create a Spring Boot project using Spring Initializr.

  1. Access Spring Initializr.
  2. Input the project metadata (group, artifact, name, etc.).
  3. Select the Spring Boot version and add the required starter dependencies.
  4. Click the PROJECT button to download the ZIP file.
  5. Extract the downloaded file and open it in your IDE.

3. Configuring the Basic Application

3.1 Creating a Controller

Once the application is successfully created, let’s create a basic REST API. Below is an example of a controller that returns Hello, World!.


@RestController
@RequestMapping("/api")
public class HelloController {
    
    @GetMapping("/hello")
    public String hello() {
        return "Hello, World!";
    }
}
    

3.2 Creating a Service Layer

The service layer handles the business logic. Below is an example of a simple service class.


@Service
public class GreetingService {
    
    public String greet() {
        return "Greetings from the Service Layer!";
    }
}
    

3.3 Database Integration

Spring Boot allows easy integration with databases through JPA. We will proceed with the example using the H2 database.


@Entity
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    
    // getters and setters
}
    

3.4 Application Properties Configuration

You can configure the database connection information in the application.properties file.


spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.h2.console.enabled=true
    

4. Running the Application

You can start the application by running the Main class within the IDE. By default, the embedded Tomcat server runs, and you can access http://localhost:8080/api/hello to verify the Hello, World! message.

5. Verifying Functionality

5.1 Installing and Configuring Postman

Use Postman to test the API. After installing Postman, send a request as follows:

  1. Open Postman and create a new request.
  2. Select the GET method and enter http://localhost:8080/api/hello in the URL.
  3. Click the Send button to send the request. Check if “Hello, World!” appears in the response.

5.2 Testing with JUnit

You can perform tests on the code you have written using JUnit. Below is an example of a unit test.


@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloControllerTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @Test
    public void testHello() throws Exception {
        mockMvc.perform(get("/api/hello"))
            .andExpect(status().isOk())
            .andExpect(content().string("Hello, World!"));
    }
}
    

6. Conclusion

You have learned how to build a simple backend application using Spring Boot and verify its functionality. I hope this course has helped you understand the basic configuration and structure of Spring Boot. In the future, try to develop mature applications by applying more complex features and design patterns.

7. References

Spring Boot Backend Development Course, Java Annotation

Spring Boot is a framework designed to simplify and accelerate Java-based application development. Spring Boot allows for the creation of independent applications more quickly and easily by utilizing various features of the Spring Framework. However, understanding Java annotations is essential for effectively leveraging Spring Boot.

1. Basic Understanding of Java Annotations

Java annotations are a way to add metadata to code. In other words, they provide information that can be used to interpret and operate on the code rather than changing or enhancing the functionality of the code itself. Annotations can primarily be used on classes, methods, fields, parameters, etc., and are used in the following format:

@AnnotationName
public void method() {
    // method code
}

2. Utilization of Annotations in Spring Boot

Spring Boot provides numerous built-in annotations to help developers easily build applications. Here, we will introduce a few frequently used annotations in Spring Boot.

2.1. @SpringBootApplication

This annotation defines the starting point class of a Spring Boot application. It is a combination of @Configuration, @EnableAutoConfiguration, and @ComponentScan.

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2.2. @RestController

This annotation defines a controller class for RESTful web services. It is a combination of @Controller and @ResponseBody, allowing all methods in the class to respond in JSON or XML format.

@RestController
@RequestMapping("/api")
public class ApiController {
    
    @GetMapping("/hello")
    public String hello() {
        return "Hello, World!";
    }
}

2.3. @Autowired

Uses Spring’s dependency injection feature to automatically inject the required beans. With this annotation, developers do not need to create objects manually.

@Service
public class UserService {
    // Service logic
}

@RestController
public class UserController {
    @Autowired
    private UserService userService;
}

2.4. @RequestMapping

Used to map HTTP requests to specific methods. This annotation allows defining the paths for REST APIs.

@RestController
@RequestMapping("/users")
public class UserController {
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable String id) {
        // Fetch user by ID
    }
}

2.5. @Entity

Used to define classes that map to database tables. This annotation allows interaction with the actual database using JPA.

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
}

3. Customizing Java Annotations

In addition to the annotations provided by default, developers can define their own annotations when needed. This can improve the readability and reusability of the code.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
    String value() default "";
}

4. Examples of Annotation Usage

Let’s look at how annotations can be utilized efficiently in real applications through examples.

4.1. Implementing a User Authentication Annotation

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresAuthentication {
}

Using the annotation shown above, you can impose authentication requirements on specific methods. This allows you to avoid redundant authentication logic for each method call.

4.2. Combining Aspect-Oriented Programming (AOP) with Annotations

By utilizing AOP in Spring Boot, you can define common functionalities that execute under specific conditions. By combining custom annotations with AOP, you can log method calls or monitor performance every time a method is invoked.

@Aspect
@Component
public class LoggingAspect {

    @Before("@annotation(RequiresAuthentication)")
    public void logBefore(JoinPoint joinPoint) {
        // Log method execution
    }
}

5. Conclusion

Java annotations are an essential component of Spring Boot development. Understanding and correctly utilizing annotations is the first step in realizing the powerful features of Spring Boot. As a result, developers can maximize the professionalism and productivity of their code. By effectively leveraging Java annotations, you can improve the maintainability and readability of applications, which are crucial elements in high-quality software development.

In addition to the annotations introduced in this course, many more annotations exist, allowing for the effective utilization of various features in Spring Boot. I hope that through this course, you will learn deeper content and apply it in practical scenarios.

6. References