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.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
12 Powerful Ways to Retrieve Beans in Spring Boot 3 – A Practical Guide

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.

Bean retrieval output
Bean retrieval output
Field injection warning
Field injection warning
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.

Spring Bootdependency-injectionCode ExamplesBean Retrieval
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.