Spring Dependency Injection Tricks: Optional, Provider, Collections, @Value & @Lazy
This article demonstrates various Spring dependency‑injection techniques—including Optional, ObjectProvider, Provider, arrays, collections, maps, @Value literals and SpEL expressions, as well as @Lazy proxies—showing the code and resulting bean representations for each approach.
Environment: Spring 5.3.23 (Java 1.8).
1. Optional
java.util.Optional<T> can be injected to lazily obtain a bean.
<code>static class CommonDAO {}
static class CommonService {
@Resource
private Optional<CommonDAO> optional;
@Override
public String toString() {
return "CommonService [optional=" + optional.orElseGet(() -> null) + "]";
}
}
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CommonDAO.class, CommonService.class)) {
System.out.println(context.getBean(CommonService.class));
}
</code>Output:
<code>CommonService [optional=xxx.CommonDAO@12d4bf7e]</code>2. ObjectFactory (ObjectProvider)
Spring’s ObjectProvider can be used to obtain a bean when needed.
<code>static class CommonService {
@Resource
private ObjectProvider<CommonDAO> provider;
@Override
public String toString() {
return "CommonService [provider=" + provider.getIfAvailable() + "]";
}
}
</code>Output:
<code>CommonService [provider=xxx.CommonDAO@11a9e7c8]</code>3. Provider (javax.inject.Provider)
javax.inject.Provider offers a standard way to retrieve a bean.
<code>static class CommonService {
@Resource
private javax.inject.Provider<CommonDAO> provider;
@Override
public String toString() {
return "CommonService [provider=" + provider.get() + "]";
}
}
</code>Output:
<code>CommonService [provider=xxx.CommonDAO@2f177a4b]</code>Note: If javax.inject.Provider is missing, add the following Maven dependency:
<code><dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
</code>4. Array Injection
<code>static interface DAO {}
static class DogDAO implements DAO {}
static class CatDAO implements DAO {}
static class CommonService {
@Resource
private DAO[] daos;
@Override
public String toString() {
return "CommonService [daos=" + Arrays.toString(this.daos) + "]";
}
}
</code>Output:
<code>CommonService [daos=[xxx.DogDAO@4445629, xxx.CatDAO@45b9a632]]</code>5. Collection Injection (List)
<code>static class CommonService {
@Resource
private List<DAO> daos;
@Override
public String toString() {
return "CommonService [daos=" + daos + "]";
}
}
</code>Output:
<code>CommonService [daos=[xxx.DogDAO@309e345f, xxx.CatDAO@56a6d5a6]]</code>6. Map Injection
<code>static class CommonService {
@Resource
private Map<String, DAO> daos;
@Override
public String toString() {
return "CommonService [daos=" + daos + "]";
}
}
</code>Output:
<code>CommonService [daos={dataTypeInejctMain.DogDAO=xxx.DogDAO@4445629, dataTypeInejctMain.CatDAO=xxx.CatDAO@45b9a632}]</code>7. Special Cases
7.1 Using @Value
Injecting literal values:
<code>static class CommonService {
@Value("${pack.name}")
private String name;
@Override
public String toString() {
return "CommonService [name=" + name + "]";
}
}
// property file
pack.name=中国🇨🇳
</code>Output:
<code>CommonService [name=中国🇨🇳]</code>Injecting via SpEL expression:
<code>static class CommonService {
@Value("#{${pack.name}}")
private CommonDAO dao;
@Override
public String toString() {
return "CommonService [name=" + dao + "]";
}
}
// property
pack.name=commonDao
// register bean
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
context.registerBean("commonDao", CommonDAO.class);
context.register(CommonService.class);
System.out.println(context.getBean(CommonService.class));
}
</code>Output:
<code>CommonService [name=xxx.CommonDAO@29176cc1]</code>Injecting basic data types (automatic conversion):
<code>static class CommonService {
@Value("666")
private int id;
@Override
public String toString() {
return "CommonService [id=" + id + "]";
}
}
</code>Output:
<code>CommonService [id=666]</code>7.2 Using @Lazy
@Lazy creates a proxy; the actual bean is instantiated only when accessed.
<code>static class CommonService {
@Resource
@Lazy
private CommonDAO commonDao;
@Override
public String toString() {
return "CommonService [commonDao=" + commonDao.getClass() + "]";
}
}
</code>Output:
<code>CommonService [commonDao=class xxx.CommonDAO$$EnhancerBySpringCGLIB$$39f36385]</code>These examples cover the most common ways to inject dependencies in Spring, helping developers choose the appropriate technique for their use case.
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.