Spring 4.x is capable of using Java Generics types as an implicit qualification for dependency injection. Now we don't have to use @Qualifier or some specialized types to overcome this limitation in previous versions.
Consider List<String> and List<Integer> . They are of same type List but have different generics types, String and Integer . Spring first matches up the type and if the type has generics then matches up the generic type. If there is only one bean available (having same type and generics) for injection then performs injection otherwise throws error: NoUniqueBeanDefinitionException
Example
This example demonstrates that even though we have two instances of RateFormatter available for dependency injection, RateCalculator is still injected with the one matched by generic type.
package com.logicbig.example;
import java.math.BigDecimal;
import java.text.NumberFormat;
public class RateFormatter<T extends Number> {
public String format(T number){
NumberFormat format = NumberFormat.getInstance();
if(number instanceof Integer){
format.setMinimumIntegerDigits(0);
}else if(number instanceof BigDecimal){
format.setMinimumIntegerDigits(2);
format.setMaximumFractionDigits(2);
}//others
return format.format(number);
}
}
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
public class RateCalculator {
@Autowired
private RateFormatter<BigDecimal> formatter;
public void calculate() {
BigDecimal rate = new BigDecimal(1053.75356);
System.out.println(formatter.format(rate));
}
}
Defining beans and running the example
package com.logicbig.example;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.math.BigDecimal;
@Configuration
public class Config {
@Bean
RateFormatter<Integer> integerRateFormatter() {
return new RateFormatter<Integer>();
}
@Bean
RateFormatter<BigDecimal> bigDecimalRateFormatter() {
return new RateFormatter<BigDecimal>();
}
@Bean
RateCalculator rateCalculator() {
return new RateCalculator();
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(Config.class);
RateCalculator bean = context.getBean(RateCalculator.class);
bean.calculate();
}
}
Output1,053.75
Example ProjectDependencies and Technologies Used: - spring-context 6.1.2 (Spring Context)
Version Compatibility: 4.0.0.RELEASE - 6.1.2 Version compatibilities of spring-context with this example: Versions in green have been tested.
- JDK 17
- Maven 3.8.1
|