Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

NPI – Spring Top – Temp – Non-Geo (Lightrun)

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

>> LEARN SPRING
NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Introduction

In this short tutorial, we'll show how to dynamically autowire a bean in Spring.

We'll start by presenting a real-world use case where dynamic autowiring might be helpful. In addition to this, we'll show how to solve it in Spring in two different ways.

2. Dynamic Autowiring Use Cases

Dynamic autowiring is helpful in places where we need to dynamically change the Spring's bean execution logic. It's practical especially in places where what code to execute is chosen based on some runtime variables.

To demonstrate a real-world use case, let's create an application that controls servers in different regions of the world. For this reason, we've created an interface with two simple methods:

public interface RegionService {
    boolean isServerActive(int serverId);

    String getISOCountryCode();
}

and two implementations:

@Service("GBregionService")
public class GBRegionService implements RegionService {
    @Override
    public boolean isServerActive(int serverId) {
        return false;
    }

    @Override
    public String getISOCountryCode() {
        return "GB";
    }
}
@Service("USregionService")
public class USRegionService implements RegionService {
    @Override
    public boolean isServerActive(int serverId) {
        return true;
    }

    @Override
    public String getISOCountryCode() {
        return "US";
    }
}

Let's say we have a website where a user has an option to check whether the server is active in the selected region. Consequently, we'd like to have a service class that dynamically changes the RegionService interface implementation given the input of the user. Undoubtedly, this is the use case where dynamic bean autowiring comes into play.

3. Using BeanFactory

BeanFactory is a root interface for accessing a Spring bean container. In particular, it contains useful methods to obtain specific beans. Since BeanFactory is also a Spring bean, we can autowire and use it directly in our class:

@Service
public class BeanFactoryDynamicAutowireService {
    private static final String SERVICE_NAME_SUFFIX = "regionService";
    private final BeanFactory beanFactory;

    @Autowired
    public BeanFactoryDynamicAutowireService(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public boolean isServerActive(String isoCountryCode, int serverId) {
        RegionService service = beanFactory.getBean(getRegionServiceBeanName(isoCountryCode), 
          RegionService.class);

        return service.isServerActive(serverId);
    }

    private String getRegionServiceBeanName(String isoCountryCode) {
        return isoCountryCode + SERVICE_NAME_SUFFIX;
    }
}

We've used an overloaded version of the getBean() method to get the bean with the given name and desired type.

And while this works, we'd really rather rely on something more idiomatic; that is, something that uses dependency injection.

4. Using Interfaces

To solve this with dependency injection, we'll rely on one of Spring's lesser-known features.

Besides standard single-field autowiring, Spring gives us an ability to collect all beans that are implementations of the specific interface into a Map:

@Service
public class CustomMapFromListDynamicAutowireService {
    private final Map<String, RegionService> servicesByCountryCode;

    @Autowired
    public CustomMapFromListDynamicAutowireService(List<RegionService> regionServices) {
        servicesByCountryCode = regionServices.stream()
                .collect(Collectors.toMap(RegionService::getISOCountryCode, Function.identity()));
    }

    public boolean isServerActive(String isoCountryCode, int serverId) {
        RegionService service = servicesByCountryCode.get(isoCountryCode);

        return service.isServerActive(serverId);
    }
}

We've created a map in a constructor that holds implementations by their country code. Furthermore, we can use it later in a method to get a particular implementation to check whether a given server is active in a specific region.

5. Conclusion

In this quick tutorial, we've seen how to dynamically autowire a bean in Spring using two different approaches.

As always, the code shown in this article is available over on GitHub.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> THE COURSE
Generic footer banner
Comments are closed on this article!