12 Powerful Ways to Retrieve Beans in Spring Boot 3 – A Practical Guide
This article presents twelve practical techniques for obtaining Spring beans—including @Autowired, @Resource, @Inject, constructor injection, ApplicationContext, BeanFactory, ObjectProvider, @Lookup, BeanFactoryUtils, BeanFactoryAnnotationUtils, custom utilities, and @Value with SpEL—complete with code examples and usage scenarios to help developers choose the most suitable approach.
In everyday Spring Boot development, retrieving beans is a frequent and crucial operation across service, repository, and controller layers. Depending on business requirements and architectural design, a single bean retrieval method may not suffice, so mastering multiple approaches is essential.
1. Introduction
The article introduces twelve ways to obtain a UserService bean, aiming to improve development efficiency, code elegance, and application robustness.
2. Practical Examples
Prepare the following class:
@Service
@Qualifier("us")
public class UserService {
public Object query() {
return "User";
}
}Below are the twelve retrieval methods applied to the above bean.
2.1 Use @Autowired
@Component
@Order(1)
public class ObtainBeanRunner1 implements CommandLineRunner {
@Autowired
private UserService userService;
@Override
public void run(String... args) throws Exception {
System.err.println("Method1: [@Autowired] - " + this.userService.query());
}
}Most common method, suitable for Spring-managed components.
2.2 Use @Resource
@Component
@Order(2)
public class ObtainBeanRunner2 implements CommandLineRunner {
@Resource
private UserService userService;
@Override
public void run(String... args) throws Exception {
System.out.println("Method2: [@Resource] - " + this.userService.query());
}
}Injects by name using the JDK annotation; the name attribute can specify the bean name.
2.3 Use @Inject
@Component
@Order(3)
public class ObtainBeanRunner3 implements CommandLineRunner {
@Inject
private UserService userService;
@Override
public void run(String... args) throws Exception {
System.err.println("Method3: [@Inject] - " + this.userService.query());
}
}Requires the jakarta.inject dependency:
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>@Inject is a JSR‑330 standard annotation and can be combined with @Named for qualified injection.
2.4 Constructor Injection
@Component
@Order(4)
public class ObtainBeanRunner4 implements CommandLineRunner {
private final UserService userService;
public ObtainBeanRunner4(UserService userService) {
this.userService = userService;
}
@Override
public void run(String... args) throws Exception {
System.out.println("Method4: [Constructor Injection (official recommendation)] - " + this.userService.query());
}
}Officially recommended; ensures immutable dependencies and avoids null‑pointer issues.
2.5 Use ApplicationContext
@Component
@Order(5)
public class ObtainBeanRunner5 implements CommandLineRunner, ApplicationContextAware {
private ApplicationContext context;
@Override
public void run(String... args) throws Exception {
UserService userService = this.context.getBean(UserService.class);
System.err.println("Method5: [ApplicationContext#getBean] - " + userService.query());
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
}Useful for dynamic retrieval at runtime, such as in utility classes or factory patterns.
2.6 Use BeanFactory
@Component
@Order(6)
public class ObtainBeanRunner6 implements CommandLineRunner, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void run(String... args) throws Exception {
UserService userService = this.beanFactory.getBean(UserService.class);
System.out.println("Method6: [BeanFactory#getBean] - " + userService.query());
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}A lighter alternative to ApplicationContext with fewer features.
2.7 Use ObjectProvider
@Component
@Order(7)
public class ObtainBeanRunner7 implements CommandLineRunner {
private final ObjectProvider<UserService> userServiceProvider;
public ObtainBeanRunner7(ObjectProvider<UserService> userServiceProvider) {
this.userServiceProvider = userServiceProvider;
}
@Override
public void run(String... args) throws Exception {
UserService userService = this.userServiceProvider.getIfUnique();
if (userService != null) {
System.err.println("Method7: [ObjectProvider] - " + userService.query());
}
}
}Safely obtains beans that may be optional or involved in circular dependencies; similar utilities include ObjectFactory and Optional.
2.8 Use @Lookup
@Component
@Order(8)
public abstract class ObtainBeanRunner8 implements CommandLineRunner {
@Lookup
public abstract UserService getUserService();
@Override
public void run(String... args) throws Exception {
UserService userService = this.getUserService();
System.out.println("Method8: [@Lookup] - " + userService.query());
}
}Ensures a new prototype bean instance on each call, solving singleton‑to‑prototype injection issues.
2.9 Use BeanFactoryUtils
@Component
@Order(9)
public class ObtainBeanRunner9 implements CommandLineRunner, BeanFactoryAware {
private ListableBeanFactory beanFactory;
@Override
public void run(String... args) throws Exception {
UserService userService = BeanFactoryUtils.beanOfType(this.beanFactory, UserService.class);
System.err.println("Method9: [BeanFactoryUtils] - " + userService.query());
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof ListableBeanFactory bf) {
this.beanFactory = bf;
}
}
}Spring’s utility class that works with a BeanFactory.
2.10 Use BeanFactoryAnnotationUtils
@Component
@Order(10)
public class ObtainBeanRunner10 implements CommandLineRunner, BeanFactoryAware {
private ListableBeanFactory beanFactory;
@Override
public void run(String... args) throws Exception {
UserService userService = BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, UserService.class, "us");
System.out.println("Method10: [BeanFactoryAnnotationUtils] - " + userService.query());
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof ListableBeanFactory bf) {
this.beanFactory = bf;
}
}
}Helps retrieve beans qualified with @Qualifier.
2.11 Custom Utility Class
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) {
SpringUtils.context = context;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}Provides a static method to fetch beans from anywhere after the context is fully initialized.
2.12 Use @Value + SpEL
@Component
@Order(12)
public class ObtainBeanRunner12 implements CommandLineRunner {
@Value("#{@userService}")
private UserService userService;
@Override
public void run(String... args) throws Exception {
System.err.println("Method12: [@Value + SpEL] - " + userService.query());
}
}References another bean via a SpEL expression; the bean name must match.
Result
The twelve methods all output the same result, confirming successful bean retrieval.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
