Full @Configuration Vs Lite Bean

Inter-bean method reference

Inter-bean method reference means even though when you call a @Bean method, it will not create a new instance.

For example, let's say we have the following POJO class:

package java_redis_db.services;

public class ThirdPartyService {
  public ThirdPartyService() {
    System.out.println("Initialised third party service");
  }
}

Given our ApplicationConfig.java has the following beans:

package java_redis_db.config;

import java_redis_db.services.AccountService;
import java_redis_db.services.ThirdPartyService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ApplicationConfig {
  private static ApplicationContext applicationContext;

  @Bean(name = "customer account service")
  public AccountService customerAccountService() {
    return new AccountService("Customer Account Service", thirdPartyService());
  }

  @Bean
  public AccountService businessAccountService() {
    return new AccountService("Business Account Service", thirdPartyService());
  }

  @Bean
  public AccountService linkedAccountService() {
    return new AccountService("Linked Account Service", thirdPartyService());
  }


  @Bean
  public ThirdPartyService thirdPartyService() {
    return new ThirdPartyService();
  }
}

Notice that in here each bean has called thirdPartyService() multiple times, however Spring will make sure that thirdPartyService() only triggered once.

It's because Spring will use CGLIB proxy to manipulate the class to check if bean thirdPartyService exists before and use that instead of making a new call.

Pasted image 20230920222044.png

Lite-mode

Lite-mode means you declare @Bean but not within a @Configuration class

For example lets change our @Configuration to @Component:

package java_redis_db.config;

import java_redis_db.services.AccountService;
import java_redis_db.services.ThirdPartyService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component // NOTE Here
public class ApplicationConfig {
  private static ApplicationContext applicationContext;

  @Bean(name = "customer account service")
  public AccountService customerAccountService() {
    return new AccountService("Customer Account Service", thirdPartyService());
  }

  @Bean
  public AccountService businessAccountService() {
    return new AccountService("Business Account Service", thirdPartyService());
  }

  @Bean
  public AccountService linkedAccountService() {
    return new AccountService("Linked Account Service", thirdPartyService());
  }


  @Bean
  public ThirdPartyService thirdPartyService() {
    return new ThirdPartyService();
  }
}

As a result, Spring will not create a CGLIB proxy for these beans anymore. And we will call ThirdPartyService multiple time:

Pasted image 20230920222017.png

The same effect when we turn off the proxyBeanMethods with @Configuration

package java_redis_db.config;  
  
import java_redis_db.services.AccountService;  
import java_redis_db.services.ThirdPartyService;  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
  
@Configuration(proxyBeanMethods = false) // NOTE here
public class ApplicationConfig {  
  private static ApplicationContext applicationContext;  
  
  @Bean(name = "customer account service")  
  public AccountService customerAccountService() {  
    return new AccountService("Customer Account Service", thirdPartyService());  
  }  
  
  @Bean  
  public AccountService businessAccountService() {  
    return new AccountService("Business Account Service", thirdPartyService());  
  }  
  
  @Bean  
  public AccountService linkedAccountService() {  
    return new AccountService("Linked Account Service", thirdPartyService());  
  }  
  
  
  @Bean  
  public ThirdPartyService thirdPartyService() {  
    return new ThirdPartyService();  
  }  
}

Pasted image 20230920222224.png