Annotations used with Spring Boot Applications

Spring Boot, a part of the Spring Framework, simplifies the development of Java applications by providing a suite of annotations that automate various aspects of coding, configuration, and deployment. These annotations help developers write clean, efficient, and maintainable code. In real-time projects, understanding and effectively utilizing these annotations is crucial for building robust applications. Below, we will explore some of the most commonly used Spring Boot annotations with code examples and detailed explanations.

1. @SpringBootApplication
 

Theory

The @SpringBootApplication annotation is a composite annotation that combines @Configuration, @EnableAutoConfiguration, and @ComponentScan annotations with their default attributes. It is typically used to mark the main class of a Spring Boot application.

Code Example

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

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

2. @RestController
 

Theory

The @RestController annotation is used to create RESTful web services. It is a combination of @Controller and @ResponseBody. It marks a class as a controller where every method returns a domain object instead of a view.

Code Example

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class MyRestController {
    @GetMapping("/greeting")
    public String greeting() {
        return "Hello, World!";
    }
}

3. @RequestMapping and @GetMapping / @PostMapping
 

Theory

@RequestMapping is used to map web requests to specific handler classes or methods. @GetMapping and @PostMapping are specialized versions of @RequestMapping for GET and POST requests, respectively.

Code Example

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class MyApiController {
    @GetMapping("/user/{id}")
    public User getUser(@PathVariable Long id) {
        // Fetch user by id
        return new User(id, "John Doe");
    }
    @PostMapping("/user")
    public User createUser(@RequestBody User user) {
        // Create and return new user
        return user;
    }
}

4. @Service
 

Theory

The @Service annotation is a specialization of the @Component annotation. It indicates that an annotated class is a "Service", originally defined by Domain-Driven Design (DDD) as an operation offered as an interface that stands alone in the model, with no encapsulated state.

Code Example

import org.springframework.stereotype.Service;
@Service
public class UserService {
    public User getUserById(Long id) {
        return new User(id, "John Doe");
    }
}

5. @Repository
 

Theory

The @Repository annotation is a specialization of @Component. It is used to indicate that the class provides the mechanism for storage, retrieval, search, update, and delete operation on objects.

Code Example

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

6. @Entity
 

Theory

The @Entity annotation specifies that the class is an entity and is mapped to a database table. It is used in JPA and Hibernate.

Code Example

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

7. @Autowired
 

Theory

The @Autowired annotation is used for automatic dependency injection. Spring's dependency injection capabilities inject object dependencies implicitly.

Code Example

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class MyController {
    private final UserService userService;
    @Autowired
    public MyController(UserService userService) {
        this.userService = userService;
    }
    public User getUser(Long id) {
        return userService.getUserById(id);
    }
}

8. @Configuration and @Bean
 

Theory

@Configuration indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime. @Bean is used to indicate that a method produces a bean to be managed by the Spring container.

Code Example

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {

    @Bean
    public UserService userService() {
        return new UserService();
    }
}

9. @Component
 

Theory

The @Component annotation marks a Java class as a bean. It is a generic stereotype for any Spring-managed component.

Code Example

import org.springframework.stereotype.Component;
@Component
public class MyComponent {
    public void performTask() {
        System.out.println("Task performed");
    }
}

10. @EnableAutoConfiguration
 

Theory

The @EnableAutoConfiguration annotation enables Spring Boot’s auto-configuration mechanism, which attempts to automatically configure your Spring application based on the jar dependencies you have added.

Code Example

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
public class MyAutoConfig {
    // Configuration beans
}

11. @RestControllerAdvice
 

Theory

The @RestControllerAdvice annotation is used to handle exceptions globally in a Spring Boot application. It is a combination of @ControllerAdvice and @ResponseBody, making it specifically suitable for RESTful services.

Code Example

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}

12. @PathVariable
 

Theory

The @PathVariable annotation is used to extract values from the URI template and assign them to method parameters in controller methods.

Code Example

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
    @GetMapping("/users/{id}")
    public User getUserById(@PathVariable("id") Long userId) {
        return new User(userId, "John Doe");
    }
}

13. @RequestParam
 

Theory

The @PathVariable annotation is used to extract query parameters from the request URL and bind them to method parameters.

Code Example

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class SearchController {
    @GetMapping("/search")
    public List<User> searchUsers(@RequestParam("name") String name) {
        // Search logic here
        return List.of(new User(1L, "John Doe"), new User(2L, "Jane Doe"));
    }
}

14. @Value
 

Theory

The @Value annotation is used to inject values into fields from a properties file or environment variables.

Code Example

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ApplicationConfig {
    @Value("${app.name}")
    private String appName;
    public String getAppName() {
        return appName;
    }
}

15. @Scheduled
 

Theory

The @Scheduled annotation is used to schedule tasks to be executed at fixed intervals or cron expressions.

Code Example

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
    @Scheduled(fixedRate = 5000)
    public void performTask() {
        System.out.println("Task performed at " + System.currentTimeMillis());
    }
    @Scheduled(cron = "0 0 * * * ?")
    public void performTaskUsingCron() {
        System.out.println("Task performed using cron at " + System.currentTimeMillis());
    }
}

16. @Transactional
 

Theory

The @Transactional annotation is used to manage transaction boundaries around method execution. It helps in maintaining data integrity and consistency.

Code Example

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class TransactionalService {
    @Transactional
    public void performTransactionalOperation() {
        // Perform operations within a transaction
    }
}

17. @Profile
 

Theory

The @Profile annotation is used to specify the profile(s) under which a bean should be created. It helps in segregating beans for different environments like development, testing, and production.

Code Example

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class ProfileConfig {
    @Bean
    @Profile("dev")
    public DataSource devDataSource() {
        return new HikariDataSource();
    }
    @Bean
    @Profile("prod")
    public DataSource prodDataSource() {
        return new DataSource();
    }
}

18. @Conditional
 

Theory

The @Conditional annotation is used to conditionally register beans based on a given condition.

Code Example

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConditionalConfig {
    @Bean
    @Conditional(MyCondition.class)
    public MyBean myBean() {
        return new MyBean();
    }
}

19. @Cacheable
 

Theory

The @Cacheable annotation is used to indicate that the result of a method should be cached.

Code Example

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class CacheService {
    @Cacheable("users")
    public User getUserById(Long id) {
        // Simulate a slow method
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new User(id, "John Doe");
    }
}

20. @EventListener
 

Theory

The @EventListener annotation is used to mark a method as an event listener, which will be invoked when an event is published.

Code Example

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class UserEventListener {
    @EventListener
    public void handleUserCreatedEvent(UserCreatedEvent event) {
        System.out.println("User created: " + event.getUser().getName());
    }
}

21. @ResponseStatus
 

Theory

The @ResponseStatus annotation is used to mark a method or an exception class with a status code and a reason message that should be returned.

Code Example

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class StatusController {
    @GetMapping("/success")
    @ResponseStatus(HttpStatus.OK)
    public String success() {
        return "Request was successful";
    }
    @GetMapping("/not-found")
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String notFound() {
        return "Resource not found";
    }
}

22. @CrossOrigin
 

Theory

The @CrossOrigin annotation is used to enable Cross-Origin Resource Sharing (CORS) on the server side, allowing requests from different origins.

Code Example

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://example.com")
public class CorsController {
    @GetMapping("/data")
    public String getData() {
        return "Cross-origin data";
    }
}

23. @RequestBody
 

Theory

The @RequestBody annotation is used to bind the HTTP request body with a domain object in method parameters. This is often used in POST and PUT requests.

Code Example

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class RequestBodyController {
    @PostMapping("/user")
    public User createUser(@RequestBody User user) {
        // Handle user creation
        return user;
    }
}

24. @ResponseBody
 

Theory

The @ResponseBody annotation indicates that the return value of a method should be bound to the web response body. This is useful in RESTful web services where you need to return data rather than a view.

Code Example

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class ResponseBodyController {
    @GetMapping("/message")
    @ResponseBody
    public String getMessage() {
        return "This is a response message";
    }
}

25. @Valid
 

Theory

The @Valid annotation is used to indicate that a method parameter should be validated against the constraints defined in its class.

Code Example

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
@RequestMapping("/api")
public class ValidationController {
    @PostMapping("/user")
    public User createUser(@Valid @RequestBody User user) {
        // Handle user creation
        return user;
    }
}

26. @JsonProperty
 

Theory

The @\JsonProperty annotation is used to map JSON property names to Java field names. This is useful when there is a mismatch between the JSON data structure and the Java object fields.

Code Example

import com.fasterxml.jackson.annotation.JsonProperty;
public class User {
    @JsonProperty("user_id")
    private Long id;
    @JsonProperty("user_name")
    private String name;
    // Constructors, getters, and setters
}

27. @JsonIgnore
 

Theory

The @JsonIgnore annotation is used to prevent a field from being serialized or deserialized.

Code Example

import com.fasterxml.jackson.annotation.JsonIgnore;
public class User {
    private Long id;
    @JsonIgnore
    private String password;
    // Constructors, getters, and setters
}

28. @ExceptionHandler
 

Theory

The @ExceptionHandler annotation is used to define a method that handles exceptions thrown by controller methods.

Code Example

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
@RestController
@RequestMapping("/api")
public class ExceptionHandlingController {
    @GetMapping("/exception")
    public String throwException() {
        throw new RuntimeException("An error occurred");
    }
    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> handleRuntimeException(RuntimeException ex) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

29. @PatchMapping
 

Theory

The @PatchMapping annotation is a specialized version of @RequestMapping for PATCH requests, used to apply partial updates to resources.

Code Example

import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class PatchController {
    @PatchMapping("/user/{id}")
    public User updateUserPartially(@PathVariable Long id, @RequestBody Map<String, Object> updates) {
        // Apply partial updates to the user
        User user = findUserById(id);
        // Update user fields with values from updates map
        return user;
    }
}

30. @DeleteMapping
 

Theory

The @DeleteMapping annotation is a specialized version of @RequestMapping for DELETE requests, used to delete resources.

Code Example

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class DeleteController {

    @DeleteMapping("/user/{id}")
    public void deleteUser(@PathVariable Long id) {
        // Delete user by id
    }
}

Conclusion

Spring Boot annotations play a pivotal role in simplifying and accelerating the development of enterprise-level applications. By abstracting and automating configuration details, these annotations allow developers to focus more on business logic and less on boilerplate code. Mastery of these annotations is essential for any developer looking to excel in real-time Spring Boot projects.

Spring Boot annotations further enhance the capabilities of a Spring Boot application, providing more tools for configuration, data handling, and event management. Understanding and leveraging these annotations can significantly improve the efficiency and maintainability of real-time Spring Boot projects.

These annotations enhance the ability to build robust and flexible APIs with Spring Boot. By understanding and utilizing these annotations, developers can handle various aspects of web requests and responses, validation, error handling, and more, leading to more efficient and maintainable code.