Backend Development 6 min read

Mastering Spring @Resource: Inject Maps, Lists, Arrays, and Single Beans

This guide demonstrates how to use Spring's @Resource annotation to inject collections such as Map, List, and array, as well as single beans, and explains resolution strategies like @Priority, @Primary, BeanFactory, ApplicationContext, @Qualifier, and custom qualifiers.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring @Resource: Inject Maps, Lists, Arrays, and Single Beans

Environment: Spring 6.1.2

1. Prepare Environment

Define an interface DAO and three implementations: WorkerDAO , StudentDAO , and TeacherDAO .

<code>public interface DAO {}
public class WorkerDAO implements DAO {}
public class StudentDAO implements DAO {}
public class TeacherDAO implements DAO {}
</code>

PersonService injects the DAO implementations.

<code>public class PersonService {
    @Resource
    private Type daos;
    public String toString() {
        return "PersonService [daos=" + daos + "]";
    }
}
</code>

The main method registers beans, refreshes the context, and prints the PersonService instance.

<code>public static void main(String[] args) {
    try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
        context.registerBean("worker", WorkerDAO.class);
        context.registerBean("student", StudentDAO.class);
        context.registerBean("teacher", TeacherDAO.class);
        context.registerBean(PersonService.class);
        context.refresh();
        System.out.println(context.getBean(PersonService.class));
    }
}
</code>

2. Type Injection

2.1 Map injection

<code>@Resource
private Map<String, DAO> daos;
</code>

Output shows the map keyed by bean names.

<code>PersonService [daos={worker=com.pack.WorkerDAO@..., student=com.pack.StudentDAO@..., teacher=com.pack.TeacherDAO@...}]
</code>

2.2 List injection

<code>@Resource
private List<DAO> daos;
</code>

Output shows the list of DAO instances.

<code>PersonService [daos=[com.pack.TeacherDAO@..., com.pack.StudentDAO@..., com.pack.WorkerDAO@...]]
</code>

2.3 Array injection

<code>@Resource
private DAO[] daos;
</code>

Output is similar to the list injection.

<code>PersonService [daos=[com.pack.TeacherDAO@..., com.pack.StudentDAO@..., com.pack.WorkerDAO@...]]
</code>

2.4 Single bean injection

<code>@Resource
private DAO daos;
</code>

When multiple DAO beans exist, Spring throws NoUniqueBeanDefinitionException .

<code>NoUniqueBeanDefinitionException: No qualifying bean of type 'com.pack.DAO' available: expected single matching bean but found 3: worker,student,teacher
</code>

Resolution methods:

@Priority – assign priority values; lower number wins.

<code>@Priority(-1)
public class WorkerDAO implements DAO {}
@Priority(-2)
public class StudentDAO implements DAO {}
@Priority(-3)
public class TeacherDAO implements DAO {}
</code>

After setting priorities, TeacherDAO is injected.

<code>PersonService [daos=com.pack.TeacherDAO@...]
</code>

@Primary – mark the preferred bean.

<code>@Primary
public class WorkerDAO implements DAO {}
</code>

Now WorkerDAO is injected.

<code>PersonService [daos=com.pack.WorkerDAO@...]
</code>

Other ways to obtain a specific bean manually:

Using BeanFactory

<code>public class PersonService implements BeanFactoryAware {
    private DAO daos;
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.daos = beanFactory.getBean("student", StudentDAO.class);
    }
}
</code>

Using ApplicationContext

<code>public class PersonService implements ApplicationContextAware {
    private DAO daos;
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        this.daos = context.getBean("student", StudentDAO.class);
    }
}
</code>

Using @Qualifier to specify bean name

<code>@Resource
@Qualifier("student")
private DAO daos;
</code>

Custom qualifier annotation example:

<code>@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
public @interface PackInject {}
</code>

Register the custom qualifier with Spring:

<code>try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
    CustomAutowireConfigurer configurer = new CustomAutowireConfigurer();
    configurer.setCustomQualifierTypes(Set.of(PackInject.class));
    context.registerBean(CustomAutowireConfigurer.class, () -> configurer);
}
</code>

Apply @PackInject to a DAO implementation and to the injection point:

<code>@PackInject
public class StudentDAO implements DAO {}
@Resource
@PackInject
private DAO daos;
</code>

All these techniques provide precise control over which bean is injected in a Spring application.

BackendJavaspringannotationdependency injectionResource
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

login 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.