Spring Project Setup
Introduction
Setting up a Spring project correctly is the foundation for building robust Java applications. In this tutorial, we'll learn how to create a Spring Boot project from scratch, understand the project structure, manage dependencies, and configure the application. By the end of this guide, you'll be able to create and run your own Spring Boot application with confidence.
Spring Boot, part of the larger Spring Framework ecosystem, simplifies the development process by providing conventions over configurations. It helps you get started quickly with minimal setup while still allowing customization when needed.
Prerequisites
Before we begin, make sure you have:
- Java Development Kit (JDK) 8 or later installed
- An IDE of your choice (IntelliJ IDEA, Eclipse, or VS Code)
- Basic knowledge of Java programming
Methods to Create a Spring Project
There are several ways to create a Spring Boot project:
- Using Spring Initializr (web-based tool)
- Using your IDE's Spring Boot integration
- Using the Spring Boot CLI
- Manual setup with Maven or Gradle
Let's explore each method, starting with the most common one.
Method 1: Using Spring Initializr
Spring Initializr is a web-based tool that generates a Spring Boot project structure with your chosen dependencies.
Step 1: Visit Spring Initializr
Go to https://start.spring.io/
Step 2: Configure Your Project
- Choose your build tool (Maven or Gradle)
- Select the language (Java, Kotlin, or Groovy)
- Choose Spring Boot version (select the latest stable version for beginners)
- Fill in project metadata:
- Group (e.g.,
com.example
) - Artifact (e.g.,
demo
) - Name and description
- Package name
- Packaging type (JAR or WAR)
- Java version
- Group (e.g.,
Step 3: Add Dependencies
For a basic web application, select:
- Spring Web
- Spring Data JPA (if you need database access)
- H2 Database (for development)
- Thymeleaf (for server-side templates)
Step 4: Generate and Download the Project
Click "Generate" to download a ZIP file containing your project.
Step 5: Extract and Import
Extract the ZIP file and import it into your IDE as a Maven or Gradle project.
Method 2: Using IDE Integration
Most modern Java IDEs offer direct integration with Spring Boot.
IntelliJ IDEA
- File → New → Project...
- Select "Spring Initializr" from the left panel
- Configure your project details and dependencies
- Click "Next" and "Finish"
Eclipse with Spring Tools
- File → New → Spring Starter Project
- Fill in the details and select dependencies
- Click "Finish"
Method 3: Using Spring Boot CLI
If you prefer the command line:
-
Install Spring Boot CLI (follow instructions at https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.installing.cli)
-
Create a new project:
spring init --name=my-project --dependencies=web,data-jpa my-project
Understanding Project Structure
After creating your project, you'll see a structure similar to this:
my-project/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── myproject/
│ │ │ └── MyProjectApplication.java
│ │ └── resources/
│ │ ├── application.properties
│ │ ├── static/
│ │ └── templates/
│ └── test/
│ └── java/
│ └── com/
│ └── example/
│ └── myproject/
│ └── MyProjectApplicationTests.java
├── pom.xml (or build.gradle)
└── README.md
Key Components:
- src/main/java/ - Contains your Java source code
- src/main/resources/ - Contains non-Java resources
- application.properties - Application configuration
- static/ - Static web resources (CSS, JS, images)
- templates/ - Template files (Thymeleaf, FreeMarker, etc.)
- src/test/ - Contains test code
- pom.xml or build.gradle - Dependency and build configuration
Understanding the Main Application Class
The main application class contains the main()
method and is annotated with @SpringBootApplication
:
package com.example.myproject;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyProjectApplication {
public static void main(String[] args) {
SpringApplication.run(MyProjectApplication.class, args);
}
}
The @SpringBootApplication
annotation combines three annotations:
@Configuration
- Marks the class as a source of bean definitions@EnableAutoConfiguration
- Tells Spring Boot to auto-configure the application@ComponentScan
- Tells Spring to scan for components in the current package and subpackages
Managing Dependencies
Maven (pom.xml)
If you're using Maven, dependencies are managed in the pom.xml
file:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
To add a new dependency, simply add a new <dependency>
element within the <dependencies>
section.
Gradle (build.gradle)
If you're using Gradle, dependencies are managed in the build.gradle
file:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
Configuration
Spring Boot uses the principle of "convention over configuration," but you can customize many aspects of your application.
application.properties
The application.properties
file in the src/main/resources
directory allows you to configure your application:
# Server configuration
server.port=8080
server.servlet.context-path=/myapp
# Database configuration
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
# Logging configuration
logging.level.root=INFO
logging.level.com.example=DEBUG
application.yml
Alternatively, you can use YAML format in application.yml
:
server:
port: 8080
servlet:
context-path: /myapp
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password: password
jpa:
database-platform: org.hibernate.dialect.H2Dialect
h2:
console:
enabled: true
logging:
level:
root: INFO
com.example: DEBUG
Creating Your First Controller
Let's create a simple REST controller to test our setup:
- Create a new Java class in your project's main package:
package com.example.myproject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
return String.format("Hello, %s!", name);
}
}
-
Run your application:
- In your IDE: Run the main application class
- With Maven:
./mvnw spring-boot:run
- With Gradle:
./gradlew bootRun
-
Open a web browser and navigate to:
http://localhost:8080/hello
You should see:
Hello, World!
Try adding a name parameter:
http://localhost:8080/hello?name=Spring
You should see:
Hello, Spring!
Running and Testing the Application
Running from IDE
Most IDEs allow you to run the application by right-clicking on the main application class and selecting "Run" or "Debug".
Running with Maven
./mvnw spring-boot:run
Running with Gradle
./gradlew bootRun
Building a JAR and Running It
With Maven:
./mvnw clean package
java -jar target/myproject-0.0.1-SNAPSHOT.jar
With Gradle:
./gradlew build
java -jar build/libs/myproject-0.0.1-SNAPSHOT.jar
Real-world Project Example: Task Manager API
Let's create a simple task manager API to demonstrate a more realistic Spring Boot application:
Step 1: Define a Task Entity
package com.example.myproject.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String description;
private boolean completed;
// Constructors
public Task() {}
public Task(String title, String description) {
this.title = title;
this.description = description;
this.completed = false;
}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isCompleted() {
return completed;
}
public void setCompleted(boolean completed) {
this.completed = completed;
}
}
Step 2: Create a Repository Interface
package com.example.myproject.repository;
import com.example.myproject.model.Task;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface TaskRepository extends JpaRepository<Task, Long> {
List<Task> findByCompleted(boolean completed);
}
Step 3: Create a Service Layer
package com.example.myproject.service;
import com.example.myproject.model.Task;
import com.example.myproject.repository.TaskRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class TaskService {
private final TaskRepository taskRepository;
@Autowired
public TaskService(TaskRepository taskRepository) {
this.taskRepository = taskRepository;
}
public List<Task> getAllTasks() {
return taskRepository.findAll();
}
public Optional<Task> getTaskById(Long id) {
return taskRepository.findById(id);
}
public List<Task> getTasksByStatus(boolean completed) {
return taskRepository.findByCompleted(completed);
}
public Task createTask(Task task) {
return taskRepository.save(task);
}
public Optional<Task> updateTask(Long id, Task taskDetails) {
return taskRepository.findById(id)
.map(task -> {
task.setTitle(taskDetails.getTitle());
task.setDescription(taskDetails.getDescription());
task.setCompleted(taskDetails.isCompleted());
return taskRepository.save(task);
});
}
public boolean deleteTask(Long id) {
return taskRepository.findById(id)
.map(task -> {
taskRepository.delete(task);
return true;
})
.orElse(false);
}
}
Step 4: Create a REST Controller
package com.example.myproject.controller;
import com.example.myproject.model.Task;
import com.example.myproject.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/tasks")
public class TaskController {
private final TaskService taskService;
@Autowired
public TaskController(TaskService taskService) {
this.taskService = taskService;
}
@GetMapping
public List<Task> getAllTasks() {
return taskService.getAllTasks();
}
@GetMapping("/{id}")
public ResponseEntity<Task> getTaskById(@PathVariable Long id) {
return taskService.getTaskById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@GetMapping("/status")
public List<Task> getTasksByStatus(@RequestParam boolean completed) {
return taskService.getTasksByStatus(completed);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Task createTask(@RequestBody Task task) {
return taskService.createTask(task);
}
@PutMapping("/{id}")
public ResponseEntity<Task> updateTask(@PathVariable Long id, @RequestBody Task task) {
return taskService.updateTask(id, task)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteTask(@PathVariable Long id) {
if (taskService.deleteTask(id)) {
return ResponseEntity.noContent().build();
}
return ResponseEntity.notFound().build();
}
}
Step 5: Configure the Database
Update your application.properties
file:
# H2 Database Configuration
spring.datasource.url=jdbc:h2:mem:taskdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
# JPA/Hibernate Properties
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true
# Enable H2 Console
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
Step 6: Add Sample Data (Optional)
Create a data.sql
file in the src/main/resources
directory:
INSERT INTO task (title, description, completed) VALUES
('Learn Spring Boot', 'Study Spring Boot fundamentals', false),
('Create a REST API', 'Implement a RESTful API using Spring Boot', false),
('Write tests', 'Create unit tests for the application', false);
Testing the Task Manager API
After starting your application, you can test the API using tools like Postman, cURL, or your browser:
-
Get all tasks:
GET http://localhost:8080/api/tasks
-
Create a new task:
POST http://localhost:8080/api/tasks
Content-Type: application/json
{
"title": "New Task",
"description": "This is a new task"
} -
Update a task:
PUT http://localhost:8080/api/tasks/1
Content-Type: application/json
{
"title": "Updated Task",
"description": "This task has been updated",
"completed": true
} -
Delete a task:
DELETE http://localhost:8080/api/tasks/1
-
Get tasks by status:
GET http://localhost:8080/api/tasks/status?completed=false
Summary
In this tutorial, we've learned:
-
How to create a Spring Boot project using various methods:
- Spring Initializr web tool
- IDE integration
- Spring Boot CLI
-
Understanding the project structure and main components:
- Main application class
- Maven/Gradle configuration
- Java source directory
- Resources directory
-
Managing dependencies with Maven or Gradle
-
Configuring the application using
application.properties
orapplication.yml
-
Creating and testing a simple REST controller
-
Building a more complex application with entities, repositories, services, and controllers
-
Running and testing the application locally
Spring Boot significantly simplifies Java application development by providing sensible defaults and auto-configuration. This allows you to focus on your application's business logic rather than infrastructure setup.
Additional Resources
- Spring Boot Official Documentation
- Spring Boot Guides
- Spring Boot API Documentation
- Spring Framework Documentation
- Baeldung Spring Tutorials
Exercises
- Create a new Spring Boot project with dependencies for web, JPA, and an in-memory database.
- Modify the basic task manager application to include due dates for tasks.
- Add validation to ensure that task titles are not empty and are between 3-100 characters.
- Implement pagination for the task list endpoint.
- Add a search functionality to find tasks by title or description.
- Create a simple frontend using Thymeleaf to interact with your task API.
Happy coding with Spring Boot!
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)