Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
46 views

Spring Boot 120 Annotations

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views

Spring Boot 120 Annotations

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

Spring Annotations

1. Dependency Injection Annotations


@Autowired
• Purpose: Used to automatically inject dependencies. It can be applied to constructors, fields, and
methods.
• Example:
@Component
public class UserService {
// Field injection
@Autowired
private UserRepository userRepository;

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

public void saveUser(User user) {


userRepository.save(user);
}
}

• Explanation: Here, @Autowired injects the UserRepository bean. Constructor injection is generally
preferred over field injection as it makes the class easier to test.
@Qualifier
• Purpose: Used when there are multiple beans of the same type and you want to specify which one
should be injected.
• Example:
@Component
public class NotificationService {

@Autowired
@Qualifier("emailService")
private MessageService messageService;

public void sendNotification(String message) {


messageService.sendMessage(message);
}
}

@Component("emailService")
public class EmailService implements MessageService {
@Override
public void sendMessage(String message) {
// Logic to send an email
}
}

@Component("smsService")
public class SmsService implements MessageService {
@Override
public void sendMessage(String message) {
// Logic to send an SMS
}
}

• Explanation: In this example, @Qualifier("emailService") ensures that the EmailService bean is


injected, even though multiple implementations of MessageService exist.
@Primary
• Purpose: Specifies the primary bean to be injected when multiple beans of the same type exist, without
needing to use @Qualifier.
• Example:
@Component
@Primary
public class DefaultNotificationService implements MessageService {
@Override
public void sendMessage(String message) {
// Default notification logic
}
}

@Component
public class AlternativeNotificationService implements MessageService {
@Override
public void sendMessage(String message) {
// Alternative notification logic
}
}

• Explanation: Here, DefaultNotificationService is injected wherever MessageService is required unless a


specific qualifier is used.
@Inject (from JSR-330)
• Purpose: An alternative to @Autowired, provided by Java’s standard dependency injection specification
(JSR-330).
• Example:
@Component
public class UserService {

@Inject
private UserRepository userRepository;

public void saveUser(User user) {


userRepository.save(user);
}
}

• Explanation: Functionally similar to @Autowired, but @Inject is part of the standard Java framework
rather than being specific to Spring.
2. Configuration Annotations
@Configuration
• Purpose: Indicates that the class can be used by the Spring IoC container as a source of bean
definitions.
• Example:
@Configuration
public class AppConfig {

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

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

• Explanation: The AppConfig class defines beans using @Bean methods, which Spring manages.
@Bean
• Purpose: Marks a method as a Spring bean producer.
• Example:
@Configuration
public class AppConfig {

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

• Explanation: The method annotated with @Bean returns an object that is registered as a bean in the
Spring context.
@Import
• Purpose: Allows importing additional @Configuration classes.
• Example:
@Configuration
@Import(DatabaseConfig.class)
public class AppConfig {
// Additional beans and configuration
}

• Explanation: Here, DatabaseConfig.class is imported, allowing its bean definitions to be included in the
Spring context.
@PropertySource
• Purpose: Used to specify a properties file to load.
• Example:
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {

@Value("${app.name}")
private String appName;

@Bean
public String getAppName() {
return appName;
}
}

• Explanation: The properties file is loaded, and its values can be injected using @Value.
@Order
• Purpose: Defines the order in which components should be processed.
• Example:
@Component
@Order(1)
public class FirstComponent {
// Component logic
}

@Component
@Order(2)
public class SecondComponent {
// Component logic
}

• Explanation: The components are processed in the order specified by the @Order annotation.
3. Component Scanning Annotations
@ComponentScan
• Purpose: Specifies the base packages to scan for Spring components.
• Example:
@Configuration
@ComponentScan(basePackages = "com.example.services")
public class AppConfig {
// Additional configuration
}

• Explanation: This tells Spring to scan the specified packages for components like @Component,
@Service, @Repository, and @Controller.
@Component
• Purpose: Generic stereotype for any Spring-managed component.
• Example:
@Component
public class EmailService {
// Email sending logic
}

• Explanation: The class is registered as a Spring bean and can be injected into other components.
@Service
• Purpose: Specialization of @Component for service classes.
• Example:
@Service
public class UserService {
// Business logic
}

• Explanation: This annotation is specifically intended for service layer components.


@Repository
• Purpose: Specialization of @Component for DAO (Data Access Object) classes.
• Example:
@Repository
public class UserRepository {
// Database access logic
}

• Explanation: Indicates that the class is responsible for interacting with the database.
@Controller
• Purpose: Specialization of @Component for web controllers.
• Example:
@Controller
public class UserController {

@GetMapping("/users")
public String getUsers(Model model) {
model.addAttribute("users", userService.getAllUsers());
return "users";
}
}

• Explanation: This annotation is used to define Spring MVC controllers.


4. Lifecycle Management Annotations
@PostConstruct
• Purpose: Indicates a method that should be run after the bean’s initialization.
• Example:
@Component
public class MyBean {

@PostConstruct
public void init() {
// Initialization logic
}
}

• Explanation: The init method is called after the bean is fully initialized by Spring.
@PreDestroy
• Purpose: Indicates a method that should be run just before the bean is destroyed.
• Example:
@Component
public class MyBean {

@PreDestroy
public void cleanup() {
// Cleanup logic
}
}

• Explanation: The cleanup method is called before the bean is removed from the Spring context.
5. Aspect-Oriented Programming (AOP) Annotations
@Aspect
• Purpose: Indicates that the class contains AOP-related advice (code that runs before, after, or around
method executions).
• Example:
@Aspect
@Component
public class LoggingAspect {

@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
}

• Explanation: The class is an aspect containing advice that runs before the execution of methods in the
specified package.
@Pointcut
• Purpose: Defines reusable expressions for where advice should be applied.
• Example:
@Aspect
@Component
public class LoggingAspect {

@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {
// Pointcut expression
}

@Before("serviceLayer()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
}

• Explanation: The serviceLayer() method is a reusable pointcut that can be used in multiple advice
methods.
@Before
• Purpose: Advice that runs before the method execution.
• Example:
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}

• Explanation: This
advice is executed before any method in the specified package runs.
@After
• Purpose: Advice that runs after the method execution, regardless of its outcome.
• Example:
@After("execution(* com.example.service.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After method: " + joinPoint.getSignature().getName());
}

• Explanation: This advice runs after the target method finishes execution.
@Around
• Purpose: Advice that surrounds the method execution, allowing you to control whether the method
executes.
• Example:
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before method: " + joinPoint.getSignature().getName());
Object result = joinPoint.proceed();
System.out.println("After method: " + joinPoint.getSignature().getName());
return result;
}

• Explanation: @Around advice can modify the flow by deciding whether or not to call joinPoint.proceed()
6. REST Controllers
@RestController
• Purpose: A specialization of @Controller that automatically adds @ResponseBody to all methods,
making it easier to create RESTful web services.
• Example:
@RestController
@RequestMapping("/api/users")
public class UserController {

@GetMapping
public List<User> getAllUsers() {
// Logic to fetch all users
return userService.getAllUsers();
}
}

• Explanation: @RestController makes it easy to create RESTful APIs by ensuring that the response is
automatically serialized to JSON or XML.
@RequestMapping
• Purpose: Used to map HTTP requests to handler methods of MVC and REST controllers. It can be
applied at both the class and method levels.
• Example:
@RestController
@RequestMapping("/api/users")
public class UserController {

@RequestMapping(value = "/{id}", method = RequestMethod.GET)


public User getUserById(@PathVariable Long id) {
// Logic to fetch a user by ID
return userService.getUserById(id);
}
}

• Explanation: @RequestMapping is versatile and can handle multiple HTTP methods (GET, POST, etc.).
It’s more generic than the specialized annotations like @GetMapping.
@GetMapping
• Purpose: A shortcut for @RequestMapping specifically for GET requests.
• Example:
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
// Logic to fetch a user by ID
return userService.getUserById(id);
}

• Explanation: @GetMapping is more concise than using @RequestMapping(method =


RequestMethod.GET).
@PostMapping
• Purpose: A shortcut for @RequestMapping specifically for POST requests.
• Example:
@PostMapping
public User createUser(@RequestBody User user) {
// Logic to create a new user
return userService.createUser(user);
}

• Explanation: @PostMapping is used for creating resources, typically handling form submissions or
JSON input.
@PutMapping
• Purpose: A shortcut for @RequestMapping specifically for PUT requests.
• Example:
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
// Logic to update an existing user
return userService.updateUser(id, user);
}

• Explanation: @PutMapping is used to update an existing resource, replacing its current state with the
new state provided.
@DeleteMapping
• Purpose: A shortcut for @RequestMapping specifically for DELETE requests.
• Example:
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
// Logic to delete a user by ID
userService.deleteUser(id);
}

• Explanation: @DeleteMapping is used to delete resources.


@PatchMapping
• Purpose: A shortcut for @RequestMapping specifically for PATCH requests, used for partial updates.
• Example:
@PatchMapping("/{id}")
public User partiallyUpdateUser(@PathVariable Long id, @RequestBody Map<String, Object> updates) {
// Logic to partially update a user
return userService.partiallyUpdateUser(id, updates);
}

• Explanation: @PatchMapping is used when you need to update a subset of a resource’s fields, rather
than the entire object.
@RequestBody
• Purpose: Used to bind the body of a POST/PUT request to a Java object.
• Example:
@PostMapping
public User createUser(@RequestBody User user) {
// Logic to create a new user
return userService.createUser(user);
}

• Explanation: @RequestBody automatically deserializes the incoming JSON payload into a Java object.
@ResponseBody
• Purpose: Used to indicate that the return value of a method should be serialized directly to the HTTP
response body.
• Example:
@GetMapping("/{id}")
@ResponseBody
public User getUserById(@PathVariable Long id) {
// Logic to fetch a user by ID
return userService.getUserById(id);
}

• Explanation: @ResponseBody is automatically included when using @RestController, but you can use
it in @Controller classes when needed.
@PathVariable
• Purpose: Used to extract values from the URI and bind them to method parameters.
• Example:
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
// Logic to fetch a user by ID
return userService.getUserById(id);
}

• Explanation: The {id} part of the URI is captured and passed to the method as a parameter.
@RequestParam
• Purpose: Used to extract query parameters from the URL and bind them to method parameters.
• Example:
@GetMapping
public List<User> getUsers(@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue
= "10") int size) {
// Logic to fetch paginated users
return userService.getUsers(page, size);
}

• Explanation: @RequestParam is used for query parameters like ?page=0&size=10. You can also set
default values.
7. Exception Handling Annotations
@ExceptionHandler
• Purpose: Used to define methods that handle specific exceptions.
• Example:
@RestController
@RequestMapping("/api/users")
public class UserController {

@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}

@ExceptionHandler(UserNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleUserNotFoundException(UserNotFoundException ex) {
return ex.getMessage();
}
}

• Explanation: When a UserNotFoundException is thrown, the handleUserNotFoundException method is


triggered.
@ResponseStatus
• Purpose: Used to set the HTTP status code for the response.
• Example:
@ExceptionHandler(UserNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleUserNotFoundException(UserNotFoundException ex) {
return ex.getMessage();
}

• Explanation: @ResponseStatus(HttpStatus.NOT_FOUND) sets the response status to 404 whenever a


UserNotFoundException is thrown.
@ControllerAdvice
• Purpose: Used to handle exceptions globally for multiple controllers.
• Example:
@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(UserNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleUserNotFoundException(UserNotFoundException ex) {
return ex.getMessage();
}

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleGeneralException(Exception ex) {
return "An error occurred: " + ex.getMessage();
}
}

• Explanation: @ControllerAdvice allows you to define a global exception handler that applies to all
controllers.
8. Data Binding Annotations
@ModelAttribute
• Purpose: Used to bind request parameters to a model object and add it to the model, often used in form
submissions.
• Example:
@Controller
@RequestMapping("/users")
public class UserController {

@GetMapping("/register")
public String showRegistrationForm(Model model) {
model.addAttribute("user", new User());
return "register";
}

@PostMapping("/register")
public String registerUser(@ModelAttribute User user) {
userService.saveUser(user);
return "redirect:/users";
}
}

• Explanation: @ModelAttribute binds form data to the User object. It’s also used to populate the model
with a default object before the view is rendered.
@InitBinder
• Purpose: Used to customize the data binding process, such as formatting dates or validating input.
• Example:
@Controller
@RequestMapping("/users")
public class UserController {

@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
@PostMapping("/register")
public String registerUser(@ModelAttribute User user) {
userService.saveUser(user);
return "redirect:/users";
}
}

• Explanation: @InitBinder allows you to configure data binding, like converting strings to date objects in
the above example.
9. Entity Mapping Annotations
@Entity
• Purpose: Indicates that a class is a JPA entity, meaning it maps to a database table.
• Example:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String username;


private String email;
// getters and setters
}

• Explanation: The @Entity annotation marks this class as an entity, which Spring Data JPA will manage
and persist in the database.
@Table
• Purpose: Specifies the name of the database table that the entity maps to.
• Example:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String username;


private String email;
// getters and setters
}

• Explanation: The @Table(name = "users") annotation explicitly specifies that the User entity maps to
the "users" table in the database.
@Column
• Purpose: Defines the mapping for a specific database column.
• Example:
@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "user_name", nullable = false)


private String username;

@Column(unique = true)
private String email;
// getters and setters
}

• Explanation: @Column lets you specify details like the column name, whether it’s nullable, or whether
it’s unique.
@Id
• Purpose: Specifies the primary key of the entity.
• Example:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// Other fields
}

• Explanation: @Id marks the field as the primary key, which uniquely identifies each entity instance in
the table.
@GeneratedValue
• Purpose: Specifies how the primary key should be generated (e.g., auto-increment).
• Example:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// Other fields
}

• Explanation: The @GeneratedValue(strategy = GenerationType.IDENTITY) annotation tells Spring


Data JPA to use the database’s identity strategy for generating unique IDs.
@EmbeddedId
• Purpose: Used for composite primary keys.
• Example:
@Entity
public class Order {

@EmbeddedId
private OrderId id;

private String product;


// Other fields
}

@Embeddable
public class OrderId implements Serializable {
private Long customerId;
private Long orderId;
// getters and setters
}
• Explanation: @EmbeddedId allows you to define a composite key using another class (like OrderId in
this example).
@OneToOne
• Purpose: Defines a one-to-one relationship between two entities.
• Example:
@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "profile_id")
private Profile profile;
// Other fields
}

• Explanation: @OneToOne is used when one entity is associated with exactly one instance of another
entity (e.g., a User has one Profile).
@OneToMany
• Purpose: Defines a one-to-many relationship between two entities.
• Example:
@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)


private List<Order> orders;
// Other fields
}

• Explanation: @OneToMany is used when one entity is associated with multiple instances of another
entity (e.g., a User has many Orders).
@ManyToOne
• Purpose: Defines a many-to-one relationship between two entities.
• Example:
@Entity
public class Order {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
@JoinColumn(name = "user_id")
private User user;
// Other fields
}

• Explanation: @ManyToOne is used when multiple instances of one entity are associated with a single
instance of another entity (e.g., many Orders belong to one User).
@ManyToMany
• Purpose: Defines a many-to-many relationship between two entities.
• Example:
@Entity
public class Student {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private List<Course> courses;
// Other fields
}

• Explanation: @ManyToMany is used when multiple instances of one entity are associated with multiple
instances of another entity (e.g., many Students enrolled in many Courses).
@JoinColumn
• Purpose: Specifies the foreign key column in a relationship.
• Example:
@Entity
public class Order {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
@JoinColumn(name = "user_id")
private User user;
// Other fields
}

• Explanation: @JoinColumn(name = "user_id") specifies the column that will hold the foreign key linking
the Order to the User.
@JoinTable
• Purpose: Specifies the join table used in many-to-many relationships.
• Example:
@Entity
public class Student {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id")
)
private List<Course> courses;
// Other fields
}

• Explanation: @JoinTable is used to create the intermediate join table in a many-to-many relationship.
@Transient
• Purpose: Indicates that a field should not be persisted in the database.
• Example:
@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String username;

@Transient
private int age; // This field will not be saved in the database
}

• Explanation: @Transient is used when you have fields that are calculated or only used temporarily and
shouldn’t be persisted in the database.
10. Repositories
@Repository
• Purpose: Indicates that a class is a Spring Data repository, which encapsulates the logic to interact with
the database.
• Example:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Custom query methods can be added here
}

• Explanation: @Repository is used to define a repository interface that extends JPA repositories like
JpaRepository or CrudRepository.
@Query
• Purpose: Used to define custom JPQL or native SQL queries.
• Example:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {

@Query("SELECT u FROM User u WHERE u.email = ?1")


User findByEmail(String email);

@Query(value = "SELECT * FROM users WHERE username = ?1", nativeQuery = true)


User findByUsernameNative(String username);
}

• Explanation: @Query allows you to write custom queries using JPQL or native SQL. It’s useful when
the default query methods are not sufficient.
11. Authentication Annotations
@EnableWebSecurity
• Purpose: Enables Spring Security’s web security support and provides the configuration needed to
secure a web application.
• Example:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll();
}
}

• Explanation: @EnableWebSecurity activates the Spring Security features and allows you to configure
them using the WebSecurityConfigurerAdapter class. This example secures all endpoints and enables a
default login form.
@CrossOrigin
• Purpose: Allows cross-origin requests on the annotated controller or method, enabling communication
between different domains.
• Example:
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "<http://example.com>")
public class UserController {

@GetMapping("/users")
public List<User> getAllUsers() {
return userService.getAllUsers();
}
}

• Explanation: @CrossOrigin(origins = "<http://example.com>") allows requests from


http://example.comto access the /api/users endpoint. This is particularly useful for enabling front-end
applications on a different domain to access your Spring Boot backend.
12. Authorization Annotations
@PreAuthorize
• Purpose: Checks the authorization before executing the method based on a given expression.
• Example:
@RestController
@RequestMapping("/api")
public class UserController {

@PreAuthorize("hasRole(’ADMIN’)")
@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}

• Explanation: @PreAuthorize("hasRole(’ADMIN’)") ensures that only users with the "ADMIN" role can
access this method. You can also use complex expressions for more detailed access control.
@PostAuthorize
• Purpose: Performs an authorization check after the method has been executed, typically used for
validating the result.
• Example:
@RestController
@RequestMapping("/api")
public class UserController {

@PostAuthorize("returnObject.username == authentication.name")
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}
}

• Explanation: @PostAuthorize("returnObject.username == authentication.name") checks if the username


of the returned User object matches the currently authenticated user’s name.
@Secured
• Purpose: Secures a method by specifying which roles are allowed to execute it.
• Example:
@RestController
@RequestMapping("/api")
public class UserController {

@Secured("ROLE_ADMIN")
@PostMapping("/users")
public User createUser(@RequestBody User user) {
return userService.createUser(user);
}
}

• Explanation: @Secured("ROLE_ADMIN") restricts access to users who have the "ROLE_ADMIN"


authority. Unlike @PreAuthorize, this annotation is simpler and only checks roles.
13. Application Configuration Annotations
@SpringBootApplication
• Purpose: A combination of three annotations: @EnableAutoConfiguration, @ComponentScan, and
@Configuration. It’s used to mark the main class of a Spring Boot application.
• Example:
@SpringBootApplication
public class MySpringBootApplication {

public static void main(String[] args) {


SpringApplication.run(MySpringBootApplication.class, args);
}
}

• Explanation: @SpringBootApplication simplifies the configuration needed to start a Spring Boot


application by combining multiple annotations.
@EnableAutoConfiguration
• Purpose: Enables Spring Boot’s auto-configuration feature, which automatically configures your
application based on the dependencies present in the classpath.
• Example:
@Configuration
@EnableAutoConfiguration
public class MyConfiguration {
// Custom beans and configurations
}

• Explanation: @EnableAutoConfiguration scans the classpath for common configurations (like


DataSource, JPA, etc.) and sets them up automatically.
@SpringBootConfiguration
• Purpose: A specialized version of @Configuration used in Spring Boot. It’s typically not used directly, as
@SpringBootApplication already includes it.
• Example:
@SpringBootConfiguration
public class MyCustomConfiguration {
// Configuration beans
}

• Explanation: While you can use @SpringBootConfiguration to define configurations, it’s usually implied
through @SpringBootApplication.
@ConfigurationProperties
• Purpose: Binds external properties (like from application.properties or application.yml) to a configuration
class.
• Example:
@ConfigurationProperties(prefix = "app")
public class AppProperties {

private String name;


private String version;

// getters and setters


}

• Explanation: @ConfigurationProperties(prefix = "app") maps properties like app.name and


app.versionfrom configuration files to fields in this class.
@Resource
• Purpose: Injects a bean by name, as defined in the context. It’s part of the JSR-250 standard.
• Example:
@Service
public class UserService {

@Resource(name = "userRepository")
private UserRepository userRepository;
}

• Explanation: @Resource(name = "userRepository") injects the bean with the specified name. This is an
alternative to @Autowired, which primarily focuses on type.
14. Testing Annotations
@SpringBootTest
• Purpose: Used to load the full Spring application context for integration tests.
• Example:
@SpringBootTest
public class UserServiceTests {

@Autowired
private UserService userService;

@Test
public void testCreateUser() {
// Test logic
}
}

• Explanation: @SpringBootTest initializes the Spring context, allowing you to test components like
services and repositories in an integrated environment.
@MockBean
• Purpose: Replaces a bean in the Spring context with a Mockito mock for testing.
• Example:
@SpringBootTest
public class UserServiceTests {

@MockBean
private UserRepository userRepository;

@Autowired
private UserService userService;

@Test
public void testCreateUser() {
// Mocked behavior and test logic
}
}

• Explanation: @MockBean is used to mock dependencies within the Spring context, making it easier to
test components in isolation.
@SpyBean
• Purpose: Spies on a real Spring bean, allowing you to override certain methods while retaining the
original behavior.
• Example:
@SpringBootTest
public class UserServiceTests {

@SpyBean
private UserService userService;

@Test
public void testCreateUser() {
// Spy on real behavior while modifying certain methods
}
}

• Explanation: @SpyBean allows you to test real objects while spying on some methods to control their
behavior during tests.
@TestPropertySource
• Purpose: Specifies additional properties or a different configuration file for testing purposes.
• Example:
@SpringBootTest
@TestPropertySource(locations = "classpath:test-application.properties")
public class UserServiceTests {

@Test
public void testCreateUser() {
// Test logic using properties from test-application.properties
}
}
• Explanation: @TestPropertySource lets you override configuration properties specifically for testing
environments.
15. Validation Annotations
@Valid
• Purpose: Triggers validation on a nested object or collection when applied in a controller or service
layer.
• Example:
@RestController
@RequestMapping("/api/users")
public class UserController {

@PostMapping
public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO user) {
// If validation passes, proceed with saving the user
return ResponseEntity.ok("User created successfully!");
}
}

• Explanation: The @Valid annotation ensures that the UserDTO object is validated according to its field
constraints before proceeding with the method logic. If validation fails, an exception is thrown
automatically.
@NotNull
• Purpose: Ensures that the annotated field is not null.
• Example:
public class UserDTO {

@NotNull(message = "Username cannot be null")


private String username;

// Other fields and getters/setters


}

• Explanation: The @NotNull annotation checks that the username field is not null. If it’s null, validation
fails and the specified error message is returned.
@NotEmpty
• Purpose: Ensures that the annotated field is not null or empty (e.g., an empty collection or string).
• Example:
public class UserDTO {

@NotEmpty(message = "Email cannot be empty")


private String email;

// Other fields and getters/setters


}

• Explanation: @NotEmpty ensures that email is neither null nor an empty string. It’s typically used for
fields where an empty value is considered invalid.
@NotBlank
• Purpose: Ensures that the annotated string is not null, empty, or consists only of whitespace.
• Example:
public class UserDTO {

@NotBlank(message = "Password cannot be blank")


private String password;
// Other fields and getters/setters
}

• Explanation: @NotBlank ensures that password is not null, empty, or just whitespace, making it more
stringent than @NotEmpty.
@Min and @Max
• Purpose: Specify the minimum and maximum allowable values for a numeric field.
• Example:
public class UserDTO {

@Min(value = 18, message = "Age should be at least 18")


@Max(value = 100, message = "Age should not exceed 100")
private int age;

// Other fields and getters/setters


}

• Explanation: @Min ensures that age is at least 18, while @Max ensures it does not exceed 100. Both
annotations are commonly used for numeric constraints.
@Size
• Purpose: Specifies the size constraints for a collection, array, or string.
• Example:
public class UserDTO {

@Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters")


private String username;

// Other fields and getters/setters


}

• Explanation: @Size ensures that username has a length between 3 and 20 characters. It’s useful for
defining constraints on string lengths, list sizes, etc.
@Email
• Purpose: Validates that a string is a well-formed email address.
• Example:
public class UserDTO {

@Email(message = "Invalid email format")


@NotEmpty(message = "Email is required")
private String email;

// Other fields and getters/setters


}

• Explanation: @Email checks that the email field is a valid email address format. It’s often combined with
@NotEmpty to ensure both format and presence.
@Pattern
• Purpose: Validates that a string matches a specified regular expression.
• Example:
public class UserDTO {

@Pattern(regexp = "^[a-zA-Z0-9]{8,20}$", message = "Password must be 8-20 characters and


alphanumeric")
private String password;
// Other fields and getters/setters
}

• Explanation: @Pattern ensures that password matches the given regular expression, enforcing rules
like length and allowed characters.
@AssertTrue and @AssertFalse
• Purpose: Validates that a boolean field is either true or false.
• Example:
public class UserDTO {

@AssertTrue(message = "Terms must be accepted")


private boolean acceptTerms;

@AssertFalse(message = "Deactivated users cannot log in")


private boolean isActive;

// Other fields and getters/setters


}

• Explanation: @AssertTrue checks that acceptTerms is true, while @AssertFalse ensures that isActive
is false.

16. Transaction Annotations


@Transactional
• Purpose: Marks a method or class as transactional, managing database transactions automatically.
• Example:
@Service
public class UserService {

@Transactional
public void registerUser(UserDTO userDTO) {
userRepository.save(userDTO.toEntity());
emailService.sendWelcomeEmail(userDTO.getEmail());
}
}

• Explanation: The @Transactional annotation ensures that either all operations within the method
complete successfully, or none of them do (rollback). In this example, if saving the user or sending the
email fails, the entire transaction is rolled back.
@Propagation
• Purpose: Specifies the transaction propagation behavior for methods (e.g., how nested transactions
should behave).
• Example:
@Transactional(propagation = Propagation.REQUIRED)
public void createUser(UserDTO userDTO) {
// Transactional code here
}

• Explanation: The Propagation.REQUIRED strategy means that if a transaction already exists, the
method will join it; otherwise, a new transaction will be created. There are other propagation strategies
like REQUIRES_NEW, SUPPORTS, etc., that determine how transactions should propagate.
@Isolation
• Purpose: Specifies the transaction isolation level (e.g., to prevent issues like dirty reads, phantom
reads).
• Example:
@Transactional(isolation = Isolation.SERIALIZABLE)
public void updateAccountBalance(Long accountId, BigDecimal amount) {
// Transactional code here
}

• Explanation: The Isolation.SERIALIZABLE level is the strictest, ensuring that transactions are fully
isolated from each other. Other levels like READ_COMMITTED and REPEATABLE_READ can also be
used based on your requirements.
@ReadOnly
• Purpose: Marks a transaction as read-only, optimizing performance by avoiding unnecessary write
locks.
• Example:
@Transactional(readOnly = true)
public List<User> getAllUsers() {
return userRepository.findAll();
}

• Explanation: The readOnly = true flag optimizes performance for read operations by reducing overhead,
as no write locks are needed.
@TransactionalEventListener
• Purpose: Listens for transactional events, triggered after a transaction is completed.
• Example:
@Component
public class UserEventListener {

@TransactionalEventListener
public void handleUserCreatedEvent(UserCreatedEvent event) {
// Handle the event after the transaction commits
}
}

• Explanation: @TransactionalEventListener ensures that the event handler only runs after the
transaction is successfully committed. This is useful for triggering post-transaction actions, like sending
notifications.
17. JSON Annotations
@JsonProperty
• Purpose: Specifies the JSON field name to map to a Java property. It can also be used to customize
the behavior of getters and setters.
• Example:
public class User {

@JsonProperty("user_name")
private String username;

@JsonProperty("age")
private int age;

// Getters and setters


}

• Explanation: The @JsonProperty("user_name") annotation maps the JSON field user_name to the
usernameproperty in the Java class. This is useful when the JSON field names don’t match your Java
property names.
@JsonIgnore
• Purpose: Excludes a property from being serialized or deserialized.
• Example:
public class User {

private String username;

@JsonIgnore
private String password;

// Getters and setters


}

• Explanation: The @JsonIgnore annotation prevents the password field from being included in the JSON
output. It’s often used for sensitive data that shouldn’t be exposed in API responses.
@JsonInclude
• Purpose: Controls when a property is included in the JSON output. It’s commonly used to skip null or
empty values.
• Example:
public class User {

private String username;

@JsonInclude(JsonInclude.Include.NON_NULL)
private String email;

// Getters and setters


}

• Explanation: @JsonInclude(JsonInclude.Include.NON_NULL) ensures that the email field is only


included if it’s not null. You can also use Include.NON_EMPTY to exclude empty strings or collections.
@JsonFormat
• Purpose: Specifies the format for date and time fields during serialization and deserialization.
• Example:
public class Event {

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")


private LocalDate eventDate;

// Getters and setters


}

• Explanation: The @JsonFormat annotation ensures that the eventDate field is serialized and
deserialized in the dd-MM-yyyy format. This is particularly useful for handling date and time formats in
JSON.
@JsonIgnoreProperties
• Purpose: Ignores specified properties during serialization and deserialization for all instances of a class.
• Example:
@JsonIgnoreProperties({"password", "ssn"})
public class User {

private String username;


private String password;
private String ssn;

// Getters and setters


}

• Explanation: The @JsonIgnoreProperties({"password", "ssn"}) annotation ensures that the password


and ssn fields are ignored for every instance of the User class. This is useful when you need to ignore
certain fields across multiple instances.
@JsonPropertyOrder
• Purpose: Specifies the order in which properties should appear in the JSON output.
• Example:
@JsonPropertyOrder({"username", "email", "age"})
public class User {

private String username;


private String email;
private int age;

// Getters and setters


}

• Explanation: The @JsonPropertyOrder({"username", "email", "age"}) annotation defines the order in


which the properties appear in the JSON output, ensuring consistent and readable JSON.
@JsonAlias
• Purpose: Allows you to specify multiple possible names for a property during deserialization.
• Example:
public class User {

@JsonAlias({"name", "user_name"})
private String username;

// Getters and setters


}

• Explanation: The @JsonAlias({"name", "user_name"}) annotation ensures that the username property
can be mapped from JSON fields named name or user_name. It’s useful when your application needs to
handle different JSON formats.
@JsonTypeInfo and @JsonSubTypes
• Purpose: Used together to handle polymorphic deserialization when you have a parent class and
multiple subclasses.
• Example:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public abstract class Animal {
private String name;
// Common fields
}

public class Dog extends Animal {


private String breed;
// Dog-specific fields
}

public class Cat extends Animal {


private boolean isIndoor;
// Cat-specific fields
}

• Explanation: @JsonTypeInfo and @JsonSubTypes together enable deserialization based on the type
property in the JSON. Depending on the value (dog or cat), the appropriate subclass is instantiated. This
is essential for handling inheritance in JSON structures.
@JsonCreator
• Purpose: Used to define a constructor or factory method for deserialization.
• Example:
public class User {

private String username;


private int age;

@JsonCreator
public User(@JsonProperty("username") String username, @JsonProperty("age") int age) {
this.username = username;
this.age = age;
}

// Getters and setters


}

• Explanation: The @JsonCreator annotation tells Jackson which constructor to use during
deserialization. In this example, the constructor is used to map the username and age fields from the
JSON input.
@JsonDeserialize and @JsonSerialize
• Purpose: Customize the deserialization and serialization process by specifying custom serializers and
deserializers.
• Example:
public class User {

@JsonDeserialize(using = CustomDateDeserializer.class)
@JsonSerialize(using = CustomDateSerializer.class)
private LocalDate birthdate;

// Getters and setters


}

// Custom Deserializer
public class CustomDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return LocalDate.parse(p.getText(), DateTimeFormatter.ofPattern("dd-MM-yyyy"));
}
}

// Custom Serializer
public class CustomDateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider serializers) throws
IOException {
gen.writeString(value.format(DateTimeFormatter.ofPattern("dd-MM-yyyy")));
}
}
• Explanation: The @JsonDeserialize and @JsonSerialize annotations allow you to specify custom logic
for parsing and formatting JSON data. This is particularly useful when working with non-standard formats
or complex types.
18. Lombok Annotations
Lombok is a library that helps reduce boilerplate code by automatically generating commonly used
methods like getters, setters, constructors, toString, etc.
@Data
• Purpose: Generates all boilerplate code for getters, setters, toString, equals, hashCode, and required
constructors.
• Example:
import lombok.Data;

@Data
public class User {
private String username;
private String email;
}

• Explanation: The @Data annotation combines @Getter, @Setter, @ToString, @EqualsAndHashCode,


and @RequiredArgsConstructor into one annotation. It’s an all-in-one annotation for typical POJOs.
@Getter and @Setter
• Purpose: Generates getter and setter methods for fields.
• Example:
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class User {
private String username;
private String email;
}

• Explanation: The @Getter and @Setter annotations generate getter and setter methods for the
specified fields, reducing the need to manually write these methods.
@ToString
• Purpose: Generates a toString() method that includes all fields of the class.
• Example:
import lombok.ToString;

@ToString
public class User {
private String username;
private String email;
}

• Explanation: The @ToString annotation creates a toString() method that represents the object’s field
values in a readable format. You can customize it to exclude specific fields or include only certain fields.
@EqualsAndHashCode
• Purpose: Generates equals() and hashCode() methods for the class.
• Example:
import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class User {
private String username;
private String email;
}

• Explanation: The @EqualsAndHashCode annotation automatically generates equals() and hashCode()


methods based on the fields of the class. These methods are essential for comparing objects and using
them in collections like Set.
@NoArgsConstructor
• Purpose: Generates a no-argument constructor.
• Example:
import lombok.NoArgsConstructor;

@NoArgsConstructor
public class User {
private String username;
private String email;
}

• Explanation: The @NoArgsConstructor annotation creates a constructor with no arguments. It’s useful
when working with frameworks that require a default constructor.
@AllArgsConstructor
• Purpose: Generates a constructor with arguments for all fields.
• Example:
import lombok.AllArgsConstructor;

@AllArgsConstructor
public class User {
private String username;
private String email;
}

• Explanation: The @AllArgsConstructor annotation creates a constructor that takes all fields as
parameters. This is helpful for creating fully initialized objects in one step.
@RequiredArgsConstructor
• Purpose: Generates a constructor with arguments for all final fields and fields marked with @NonNull.
• Example:
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class User {
private final String username;
private String email;
}

• Explanation: The @RequiredArgsConstructor annotation creates a constructor for fields that are final or
marked as @NonNull. This is useful for immutable objects or enforcing mandatory fields.

19. API Documentation Annotations


@ApiOperation
• Purpose: Describes a single operation (an endpoint) in an API.
• Example:
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {

@ApiOperation(value = "Get user details by username", notes = "Provide a username to look up


specific user details")
@GetMapping("/user")
public User getUser(String username) {
// Method implementation
return new User();
}
}

• Explanation: The @ApiOperation annotation describes the endpoint’s purpose, helping to generate
clear and detailed API documentation.
@ApiResponse
• Purpose: Describes the response of an operation, including status codes and messages.
• Example:
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

@ApiResponses({
@ApiResponse(code = 200, message = "Successfully retrieved user"),
@ApiResponse(code = 404, message = "User not found")
})
@GetMapping("/user")
public User getUser(String username) {
// Method implementation
return new User();
}
}

• Explanation: The @ApiResponses annotation lists possible responses for an endpoint, including HTTP
status codes and corresponding messages.
@ApiModel and @ApiModelProperty
• Purpose: Annotate model classes and properties for API documentation.
• Example:
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(description = "Details about the user")


public class User {

@ApiModelProperty(value = "The username of the user")


private String username;

@ApiModelProperty(value = "The email of the user")


private String email;

// Getters and setters


}

• Explanation: @ApiModel is used on a class to provide a description of the model, and


@ApiModelProperty is used on fields to describe their purpose in the API documentation.
@EnableSwagger2
• Purpose: Enables Swagger 2 for the application.
• Example:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example"))
.paths(PathSelectors.any())
.build();
}
}

• Explanation: The @EnableSwagger2 annotation is used to activate Swagger 2 for API documentation.
It’s typically placed in a configuration class.
20. OpenAPI Annotations
@OpenAPIDefinition
• Purpose: Defines the global configuration for the OpenAPI documentation.
• Example:
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.Contact;
import org.springframework.context.annotation.Configuration;

@Configuration
@OpenAPIDefinition(
info = @Info(
title = "User API",
version = "1.0",
description = "API for managing users",
contact = @Contact(name = "Support Team", email = "support@example.com")
)
)
public class OpenApiConfig {
// Configuration class for OpenAPI documentation
}

• Explanation: The @OpenAPIDefinition annotation provides global settings for OpenAPI documentation,
including metadata like the title, version, description, and contact information.
@Tag
• Purpose: Organizes operations under a specific tag (group).
• Example:
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Tag(name = "User Management", description = "Operations related to user management")
public class UserController {

@GetMapping("/user")
public User getUser(String username) {
// Method implementation
return new User();
}
}

• Explanation: The @Tag annotation groups operations (endpoints) under a specific category, making the
documentation more organized.
@Operation
• Purpose: Describes a single API operation.
• Example:
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

@Operation(summary = "Get user by username", description = "Fetches user details based on the
provided username")
@GetMapping("/user")
public User getUser(String username) {
// Method implementation
return new User();
}
}

• Explanation: The @Operation annotation provides a summary and detailed description of the API
endpoint
21. Conditional Annotations
@Conditional
• Purpose: Allows conditional bean registration based on custom conditions implemented via a Condition
interface.
• Example:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

@Bean
@Conditional(OnMyCondition.class)
public MyBean myBean() {
return new MyBean();
}
}

• Explanation: The @Conditional annotation takes a class implementing Condition as a parameter. The
bean (myBean) will only be created if the condition specified in OnMyCondition is met.
@ConditionalOnBean
• Purpose: The bean is created only if a specific bean (or beans) is already present in the application
context.
• Example:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConditionalOnBean;

@Configuration
public class AppConfig {

@Bean
public SomeService someService() {
return new SomeService();
}

@Bean
@ConditionalOnBean(SomeService.class)
public AnotherService anotherService() {
return new AnotherService();
}
}

• Explanation: The @ConditionalOnBean(SomeService.class) annotation ensures that anotherService is


only created if someService is present in the application context.
@ConditionalOnMissingBean
• Purpose: The bean is created only if a specific bean (or beans) is not already present in the application
context.
• Example:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConditionalOnMissingBean;

@Configuration
public class AppConfig {

@Bean
@ConditionalOnMissingBean(SomeService.class)
public DefaultService defaultService() {
return new DefaultService();
}
}

• Explanation: The @ConditionalOnMissingBean(SomeService.class) annotation ensures that


defaultService is only created if SomeService is not already present in the application context.
@ConditionalOnClass
• Purpose: The bean is created only if a specified class (or classes) is present on the classpath.
• Example:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConditionalOnClass;

@Configuration
public class AppConfig {

@Bean
@ConditionalOnClass(name = "com.example.SomeLibrary")
public LibraryBean libraryBean() {
return new LibraryBean();
}
}

• Explanation: The @ConditionalOnClass(name = "com.example.SomeLibrary") annotation ensures that


libraryBean is only created if SomeLibrary is available on the classpath.
@ConditionalOnMissingClass
• Purpose: The bean is created only if a specified class (or classes) is not present on the classpath.
• Example:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConditionalOnMissingClass;

@Configuration
public class AppConfig {

@Bean
@ConditionalOnMissingClass("com.example.SomeLibrary")
public MissingLibraryBean missingLibraryBean() {
return new MissingLibraryBean();
}
}

• Explanation: The @ConditionalOnMissingClass("com.example.SomeLibrary") annotation ensures that


missingLibraryBean is only created if SomeLibrary is not available on the classpath.
@ConditionalOnProperty
• Purpose: The bean is created only if a specific property has a specific value.
• Example:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConditionalOnProperty;

@Configuration
public class AppConfig {

@Bean
@ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")
public FeatureBean featureBean() {
return new FeatureBean();
}
}

• Explanation: The @ConditionalOnProperty(name = "app.feature.enabled", havingValue =


"true")annotation ensures that featureBean is only created if the property app.feature.enabled is set to
true in the configuration.
@ConditionalOnExpression
• Purpose: The bean is created only if a SpEL (Spring Expression Language) expression evaluates to
true.
• Example:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConditionalOnExpression;

@Configuration
public class AppConfig {

@Bean
@ConditionalOnExpression("#{systemProperties[’app.mode’] == ’production’}")
public ProductionBean productionBean() {
return new ProductionBean();
}
}

• Explanation: The @ConditionalOnExpression("#{systemProperties[’app.mode’] ==


’production’}")annotation ensures that productionBean is only created if the expression evaluates to true.
In this case, it checks if the system property app.mode is set to production.
@ConditionalOnResource
• Purpose: The bean is created only if a specified resource (like a file) is available.
• Example:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConditionalOnResource;

@Configuration
public class AppConfig {

@Bean
@ConditionalOnResource(resources = "classpath:config.properties")
public ResourceBean resourceBean() {
return new ResourceBean();
}
}

• Explanation: The @ConditionalOnResource(resources = "classpath:config.properties") annotation


ensures that resourceBean is only created if the config.properties file is present on the classpath.

You might also like