Master Spring Boot 3: 171 Real-World Cases and Advanced Techniques

This article presents a continuously updated collection of 171 Spring Boot 3 practical cases, covering advanced topics such as global exception handling, custom interceptors, bean retrieval, configuration imports, startup runners, bean definition modification, initialization methods, custom scopes, and graceful shutdown, with full code examples and a free PDF ebook.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master Spring Boot 3: 171 Real-World Cases and Advanced Techniques

Spring Boot 3 Practical Case Collection

PDF ebook updated to over 130 articles, now featuring 171 cases with ongoing updates.

We promise permanent free updates for all subscribers.

1. Introduction

This article details multiple advanced features of the Spring framework, including exception handling, interceptors, container object retrieval, configuration import, startup enhancements, bean definition modification, initialization methods, bean lifecycle management, container shutdown, and custom scopes.

2. Practical Cases

2.1 Global Exception Handling

When an exception occurs in an API, a global handler can provide user‑friendly messages.

@RequestMapping("/test")
@RestController
public class TestController {
  @GetMapping("/division")
  public String division(@RequestParam("a") int a, @RequestParam("b") int b) {
    return String.valueOf(a / b);
  }
}

Accessing http://127.0.0.1:8080/test/division?a=10&b=0 triggers an error.

@RestControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(Exception.class)
  public String handleException(Exception e) {
    if (e instanceof ArithmeticException) {
      return "Parameter error";
    }
    return "Internal server error";
  }
}

2.2 Custom Interceptor

Spring MVC interceptors allow access to HttpServletRequest and HttpServletResponse and define three methods: preHandle, postHandle, and afterCompletion.

public class AuthInterceptor implements HandlerInterceptor {
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String requestUrl = request.getRequestURI();
    return checkAuth(requestUrl);
  }
  private boolean checkAuth(String requestUrl) {
    System.out.println("===权限验证===");
    return true;
  }
}
@Configuration
public class WebAuthConfig implements WebMvcConfigurer {
  @Bean
  public AuthInterceptor getAuthInterceptor() {
    return new AuthInterceptor();
  }
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(getAuthInterceptor());
  }
}

2.3 Accessing Spring Container Objects

Implement BeanFactoryAware or ApplicationContextAware to obtain beans programmatically.

@Service
public class StudentService implements BeanFactoryAware {
  private BeanFactory beanFactory;
  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    this.beanFactory = beanFactory;
  }
  public void add() {
    Student student = (Student) beanFactory.getBean("student");
  }
}
@Service
public class CommonService implements ApplicationContextAware {
  private ApplicationContext applicationContext;
  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
  }
  public void add() {
    Student student = (Student) applicationContext.getBean("student");
  }
}

2.4 Import Configuration

Use @Import to bring ordinary classes into the container, or combine with @Configuration, @ImportResource, @PropertySource. Custom import mechanisms include ImportSelector and ImportBeanDefinitionRegistrar.

public class A {}

@Import(A.class)
@Configuration
public class TestConfiguration {}
public class AImportSelector implements ImportSelector {
  private static final String CLASS_NAME = "com.pack.service.A";
  @Override
  public String[] selectImports(AnnotationMetadata importingClassMetadata) {
    return new String[]{CLASS_NAME};
  }
}

@Import(AImportSelector.class)
@Configuration
public class TestConfiguration {}
public class AImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
  @Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    RootBeanDefinition beanDefinition = new RootBeanDefinition(A.class);
    registry.registerBeanDefinition("a", beanDefinition);
  }
}

@Import(AImportBeanDefinitionRegistrar.class)
@Configuration
public class TestConfiguration {}

2.5 Additional Startup Features

Implement ApplicationRunner or CommandLineRunner to execute code during application startup.

@Component
public class MyApplicationRunner implements ApplicationRunner {
  @Override
  public void run(ApplicationArguments args) throws Exception {
    System.out.println("项目启动时执行附加功能,加载系统参数...");
    Properties properties = new Properties();
    try (InputStream inputStream = new FileInputStream("application.properties")) {
      properties.load(inputStream);
      String systemParam = properties.getProperty("system.param");
      System.out.println("加载的系统参数值:" + systemParam);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

2.6 Modify BeanDefinition

Implement BeanFactoryPostProcessor to alter bean definitions before instantiation.

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
    builder.addPropertyValue("id", 123);
    builder.addPropertyValue("name", "Dylan Smith");
    dlbf.registerBeanDefinition("user", builder.getBeanDefinition());
  }
}

2.7 Initialization Methods

Use @PostConstruct or implement InitializingBean to run initialization logic.

@Service
public class AService {
  @PostConstruct
  public void init() {
    System.out.println("===初始化===");
  }
}
@Service
public class BService implements InitializingBean {
  @Override
  public void afterPropertiesSet() throws Exception {
    System.out.println("===初始化===");
  }
}

2.8 BeanPostProcessor

Implement BeanPostProcessor to add logic before or after bean initialization.

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof User user) {
      user.setUserName("Pack_xg");
    }
    return bean;
  }
}

2.9 Container Shutdown

Implement DisposableBean (and optionally InitializingBean) to execute logic before the Spring container is destroyed.

@Service
public class DService implements InitializingBean, DisposableBean {
  @Override
  public void destroy() throws Exception {
    System.out.println("DisposableBean destroy");
  }
  @Override
  public void afterPropertiesSet() throws Exception {
    System.out.println("InitializingBean afterPropertiesSet");
  }
}

2.10 Custom Scope

Create a thread‑local scope by implementing Scope, register it with CustomScopeConfigurer, and apply it via @Scope("threadLocalScope").

public class ThreadLocalScope implements Scope {
  private static final ThreadLocal<Object> THREAD_LOCAL_SCOPE = new ThreadLocal<>();
  @Override
  public Object get(String name, ObjectFactory<?> objectFactory) {
    Object value = THREAD_LOCAL_SCOPE.get();
    if (value != null) {
      return value;
    }
    Object object = objectFactory.getObject();
    THREAD_LOCAL_SCOPE.set(object);
    return object;
  }
  @Override
  public Object remove(String name) {
    THREAD_LOCAL_SCOPE.remove();
    return null;
  }
  @Override
  public void registerDestructionCallback(String name, Runnable callback) {}
  @Override
  public Object resolveContextualObject(String key) { return null; }
  @Override
  public String getConversationId() { return null; }
}
@Configuration
public class ScopeConfig {
  @Bean
  public CustomScopeConfigurer customScopeConfigurer() {
    CustomScopeConfigurer csc = new CustomScopeConfigurer();
    csc.addScope("threadLocalScope", new ThreadLocalScope());
    return csc;
  }
}
@Scope("threadLocalScope")
@Service
public class CService {
  public void add() {}
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Case StudyJavaBackend DevelopmentSpring BootSpring Framework
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.