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.
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:
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();
}
}