βœ… 1. @Async – Asynchronous Execution

πŸ”Ή Code:

@Configuration
@EnableAsync
public class AppConfig {}

πŸ”Έ Explanation:

  • @Configuration: Tells Spring this class defines beans.
  • @EnableAsync: Enables Spring’s ability to run methods asynchronously using @Async.

πŸ”Ή Service:

@Service
public class EmailService {

@Async
public void sendEmail(String to) {
System.out.println("Sending email to: " + to);
try {
Thread.sleep(3000); // simulate delay
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Email sent to: " + to);
}
}

πŸ”Έ Explanation:

  • @Service: Makes this a Spring-managed bean.
  • @Async: Runs sendEmail() in a new thread (non-blocking).
  • Thread.sleep(3000): Simulates a 3-second delay as if sending an email.

πŸ”Ή Controller:

@RestController
public class NotificationController {

@Autowired
private EmailService emailService;

@GetMapping("/notify")
public String notifyUser() {
emailService.sendEmail("[email protected]");
return "Notification triggered!";
}
}

πŸ”Έ Explanation:

  • When you access /notify, Spring immediately responds, while sendEmail continues to run in the background thread.

βœ… 2. @ControllerAdvice – Global Exception Handling

πŸ”Ή Code:

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<String> handleIllegalArg(IllegalArgumentException ex) {
return new ResponseEntity<>("Invalid input: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleAll(Exception ex) {
return new ResponseEntity<>("Server Error: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

πŸ”Έ Explanation:

  • @ControllerAdvice: Applies to all controllers.
  • @ExceptionHandler: Specifies which exception this method handles.
  • ResponseEntity: Allows you to return custom status and message.

πŸ”Ή Controller:

@RestController
public class TestController {

@GetMapping("/error")
public String throwError() {
throw new IllegalArgumentException("Bad ID");
}
}

πŸ”Έ Result:

Visiting /error returns 400 Bad Request with "Invalid input: Bad ID"

βœ… 3. MockMvc – Controller Testing

πŸ”Ή Code:

@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerTest {

@Autowired
private MockMvc mockMvc;

@Test
public void testHelloEndpoint() throws Exception {
mockMvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string("Hello Spring"));
}
}

πŸ”Έ Explanation:

  • @WebMvcTest: Loads only web layer (not full context).
  • MockMvc: Used to simulate HTTP requests to test controllers.
  • get("/hello"): Sends a fake GET request to /hello.

πŸ”Ή Controller:

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

βœ… 4. CORS Configuration

πŸ”Ή Code:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST");
}
}

πŸ”Έ Explanation:

  • Allows JavaScript frontend (e.g., React on port 3000) to call Spring backend.
  • /api/** matches any endpoint starting with /api.

βœ… 5. Custom Converter – String to User

πŸ”Ή Converter:

@Component
public class StringToUserConverter implements Converter<String, User> {

@Autowired
private UserRepository userRepository;

@Override
public User convert(String id) {
return userRepository.findById(id).orElse(null);
}
}

πŸ”Έ Explanation:

  • Converts String ID into User object using repository.
  • Spring auto-uses this in @RequestParam, @PathVariable, or form binding.

πŸ”Ή Usage:

@GetMapping("/user")
public String getUser(User user) {
return "User: " + user.getName();
}

βœ… 6. Static Resources

πŸ”Ή Example Directory:

src/main/resources/static/js/script.js

πŸ”Ή Access in Browser:

http://localhost:8080/js/script.js

πŸ”Έ Explanation:

  • Spring Boot automatically maps /static/** to serve static files.

βœ… 7. Custom Annotation + AOP Logging

πŸ”Ή Annotation:

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

πŸ”Ή Aspect:

@Aspect
@Component
public class LoggingAspect {

@Around("@annotation(LogExecutionTime)")
public Object logTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed(); // Execute method
long end = System.currentTimeMillis();
System.out.println("Execution Time: " + (end - start) + " ms");
return result;
}
}

πŸ”Ή Service:

@Service
public class MyService {

@LogExecutionTime
public void process() throws InterruptedException {
Thread.sleep(2000);
}
}

Similar Posts