Backend Development 17 min read

15 Practical Spring Framework Tips for Developers

This article presents fifteen useful Spring techniques—including bean retrieval, event handling, custom interceptors, retry mechanisms, global exception handling, startup initialization, bean lifecycle methods, resource cleanup, dynamic configuration injection, conditional bean registration, caching, transaction management, bean loading order, AOP aspects, and conditional bean creation—each illustrated with clear Java code examples.

IT Services Circle
IT Services Circle
IT Services Circle
15 Practical Spring Framework Tips for Developers

1. Retrieve Spring Bean Instances

Implement ApplicationContextAware or BeanFactoryAware to obtain beans from the Spring container, typically by overriding setApplicationContext or setBeanFactory .

@Service
public class TianLuoService implements ApplicationContextAware {
    private ApplicationContext context;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
    public void friedTianLuo() {
        TianLuo tianluo = (TianLuo) context.getBean("tianluo");
        tianluo.fried();
    }
}
@Service
public class TianLuoService implements BeanFactoryAware {
    private BeanFactory beanFactory;
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
    public void friedTianLuo() {
        TianLuo tianluo = (TianLuo) beanFactory.getBean("tianluo");
        tianluo.fried();
    }
}

2. Spring Observer Pattern

Define a custom event extending ApplicationEvent and a listener implementing ApplicationListener<MessageEvent> . Publish the event via ApplicationEventPublisher when needed.

public class MessageEvent extends ApplicationEvent {
    public MessageEvent(Object source) { super(source); }
}
@Component
public class MessageListener implements ApplicationListener
{
    @Override
    public void onApplicationEvent(MessageEvent event) {
        System.out.println("User registration succeeded: " + event.getSource());
    }
}
@RestController
public class UserController implements ApplicationContextAware {
    @Autowired private UserService userService;
    @Autowired private ApplicationEventPublisher publisher;
    @RequestMapping("springListenRegister")
    public String springListenRegister(UserParam param) {
        userService.addUser(param);
        publisher.publishEvent(new MessageEvent("666"));
        return "SUCCESS";
    }
}

3. Custom Interceptor

Implement HandlerInterceptor to intercept requests, then register it via WebMvcConfigurer .

@Component
public class CustomInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("Request URL: " + request.getRequestURL());
        System.out.println("Request Method: " + request.getMethod());
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv) {
        System.out.println("Response Status: " + response.getStatus());
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("Request Completed");
    }
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired private CustomInterceptor customInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor).addPathPatterns("/**");
    }
}

4. @Retryable for Automatic Retries

Use @Retryable to retry a method on specified exceptions, configuring attempts and back‑off policy.

@Retryable(value = {IOException.class}, maxAttempts = 5, backoff = @Backoff(delay = 1000))
public void processFile() throws IOException {
    // simulated file processing that may throw IOException
}

5. Global Exception Handling with @RestControllerAdvice

Centralize exception handling by annotating a class with @RestControllerAdvice and defining @ExceptionHandler methods.

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ArithmeticException.class)
    public ResponseEntity
handleArithmetic(ArithmeticException ex) {
        return new ResponseEntity<>("Error: Division by zero is not allowed!", HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity
handleIllegalArg(IllegalArgumentException ex) {
        return new ResponseEntity<>("Error: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }
    @ExceptionHandler(Exception.class)
    public ResponseEntity
handleOther(Exception ex) {
        return new ResponseEntity<>("Internal server error: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

6. Startup Parameter Initialization & Cache Warm‑up

Implement CommandLineRunner or ApplicationRunner to execute code when the application starts.

@Component
public class CachePreloader implements CommandLineRunner {
    @Override
    public void run(String... args) {
        System.out.println("Preloading cache...");
        // cache loading logic here
    }
}

7. Common Bean Initialization Methods

Use @PostConstruct , implement InitializingBean , or specify initMethod in @Bean definitions.

@Component
public class MyBean {
    @PostConstruct
    public void init() { System.out.println("Bean initialized via @PostConstruct"); }
}
@Component
public class MyBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() { System.out.println("Bean initialized via InitializingBean"); }
}
@Configuration
public class AppConfig {
    @Bean(initMethod = "init")
    public MyBean myBean() { return new MyBean(); }
}
public class MyBean { public void init() { System.out.println("Bean initialized via initMethod"); } }

8. Actions Before Container Shutdown

Implement DisposableBean or annotate a method with @PreDestroy to release resources.

@Component
public class MyResource implements DisposableBean {
    @Override
    public void destroy() { System.out.println("Resource released during shutdown"); }
}
@Component
public class MyResource {
    @PreDestroy
    public void cleanup() { System.out.println("Resource released using @PreDestroy"); }
}

9. Dynamic Configuration Injection with @Value

Inject properties from application.properties or application.yml into bean fields using @Value .

# application.properties
app.name=MySpringApp
app.version=1.0.0
app.description=This is a simple Spring application.
@Component
public class AppConfig {
    @Value("${app.name}") private String appName;
    @Value("${app.version}") private String appVersion;
}

10. Dynamic Bean Injection

Use @Autowired with @Qualifier or @Resource to inject specific beans.

@Component
public class ServiceA { public void execute() { System.out.println("ServiceA executed"); } }
@Component
public class ServiceB { public void execute() { System.out.println("ServiceB executed"); } }
@Component
public class ClientService {
    private final ServiceA serviceA;
    @Autowired
    public ClientService(@Qualifier("serviceA") ServiceA serviceA) { this.serviceA = serviceA; }
    public void doSomething() { serviceA.execute(); }
}
@Component
public class MyService {
    @Resource(name = "myBean") private MyBean myBean;
    public void doSomething() { myBean.execute(); }
}

11. Local Caching with @Cacheable

Configure a cache manager (e.g., Caffeine) and annotate methods with @Cacheable to store results.

@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cm = new CaffeineCacheManager("book");
        cm.setCaffeine(caffeineCacheBuilder());
        return cm;
    }
    Caffeine
caffeineCacheBuilder() {
        return Caffeine.newBuilder().maximumSize(500).expireAfterWrite(10, TimeUnit.MINUTES);
    }
}
@Cacheable("book")
public BookVO queryBookById(Integer bookId) {
    BookPO po = bookRepository.queryBookById(bookId);
    BookVO vo = new BookVO();
    BeanUtils.copyProperties(po, vo);
    log.info("Query book: {}", bookId);
    return vo;
}

12. Transaction Management

Programmatic transactions use TransactionTemplate ; declarative transactions use @Transactional .

@Service
public class UserService {
    @Autowired private UserRepository repo;
    @Autowired private PlatformTransactionManager tm;
    public void createUserWithProgrammingStyle(User user) {
        TransactionTemplate tt = new TransactionTemplate(tm);
        tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        tt.execute(status -> { repo.save(user); return null; });
    }
    @Transactional
    public void createUserWithDeclarativeStyle(User user) { repo.save(user); }
}

13. Specifying Bean Loading Order

Use @DependsOn to declare dependencies or @Order / Ordered to set explicit order.

@Component
@DependsOn("beanB")
public class BeanA { }
@Component
public class BeanB { }
@Component
@Order(1)
public class BeanE { }
@Component
@Order(2)
public class BeanF { }

14. Aspect‑Oriented Programming with @Aspect

Define an aspect class with @Before and @After advices to log method execution.

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.demo.service.MyService.performTask(..))")
    public void logBefore() { System.out.println("Before executing performTask()"); }
    @After("execution(* com.example.demo.service.MyService.performTask(..))")
    public void logAfter() { System.out.println("After executing performTask()"); }
}

15. Conditional Bean Registration with @Conditional

Apply @Conditional on @Bean methods to load beans only when custom conditions are met.

@Configuration
public class ServiceConfig {
    @Bean
    @Conditional(DatabaseServiceCondition.class)
    public DatabaseService databaseService() { return new DatabaseService(); }
    @Bean
    @Conditional(MessageServiceCondition.class)
    public MessageService messageService() { return new MessageService(); }
}
backendJavaSpringSpringBootDependencyInjectiontips
IT Services Circle
Written by

IT Services Circle

Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.

0 followers
Reader feedback

How this landed with the community

login 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.