Why Spring @Bean Aliases Disappear in Map Injection and How to Restore Them
When a Spring @Bean is defined with multiple names, only the first name becomes the bean identifier while the others become aliases that are ignored by type‑based Map injection, causing dynamic data‑source routing to fail unless the aliases are manually added back into the map.
In Spring, defining a bean with @Bean(name = {"aliasTestService", "aliasTestServiceDemo"}) registers the first name as the actual bean name and the remaining names as aliases. When injecting beans by type using a Map<String, Interface>, Spring only includes the primary bean names in the map’s key set, so the aliases are omitted.
Scenario
When implementing dynamic data‑source routing with
org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource, a JAR package may need to expose several data‑source beans to a consuming team. The consuming code injects a Map<String, DataSource> to obtain all available data sources. Because the required alias names are not present in the map, the routing logic cannot locate the correct data source, leading to duplicate connections or failures.
Root Cause
Spring’s bean registration process treats the first entry in the name array as the bean’s canonical name and registers the rest as aliases. During type‑based bean retrieval, Spring’s DefaultListableBeanFactory#doGetBeanNamesForType filters out any name that is an alias ( !isAlias(beanName)), so aliases never appear as keys in a Map<String, …> injection.
Conclusion
Bean aliases are excluded from the key set of a Map<String, Object> injection, which prevents the alias‑based lookup required for dynamic data‑source switching.
Solution
To make aliases available, manually copy them into the injected map after Spring populates it. The following configuration demonstrates how to retrieve each bean’s aliases from the ApplicationContext and insert them into the map:
@Configuration
public class AliasTestConfiguration {
@Bean(name = {"aliasTestService", "aliasTestServiceDemo"})
public AliasTestService aliasTestService1() {
return new AliasTestServiceImpl();
}
@Bean
public AliasTestService aliasTestService2() {
return new AliasTestServiceImpl2();
}
@Bean
public AutowireTest autowireTest(Map<String, AliasTestService> aliasTestServiceMap, ApplicationContext context) {
Map<String, AliasTestService> serviceHashMap = new HashMap<>(aliasTestServiceMap);
for (Map.Entry<String, AliasTestService> entry : aliasTestServiceMap.entrySet()) {
String beanName = entry.getKey();
AliasTestService service = entry.getValue();
String[] aliases = context.getAliases(beanName);
for (String alias : aliases) {
serviceHashMap.put(alias, service);
}
}
return new AutowireTest(serviceHashMap);
}
}This code iterates over the original map, obtains each bean’s aliases via ApplicationContext#getAliases, and adds (alias, bean) pairs to a new map that is then used by the routing data source.
Spring Version Used
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
</parent>By applying this approach, the required alias names become part of the map, enabling successful dynamic data‑source switching.
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.
Cognitive Technology Team
Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.
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.
