Backend Development 6 min read

Why Field Injection Is Not Recommended in Spring and Preferred Alternatives

This article explains why Spring’s field injection is discouraged, outlines constructor‑based, setter‑based, and field‑based injection methods with code examples, discusses the drawbacks of field injection such as hidden dependencies and poor testability, and recommends using constructor injection for required beans and setter injection for optional ones.

Java Captain
Java Captain
Java Captain
Why Field Injection Is Not Recommended in Spring and Preferred Alternatives

Introduction: While coding in IntelliJ IDEA, a warning appears for field injection such as:

@Autowire
private JdbcTemplate jdbcTemplate;

The warning states that field injection is not recommended; the Spring team advises always using constructor‑based dependency injection and assertions for mandatory dependencies.

Spring defines three injection types: constructor‑based, setter‑based, and field‑based.

Constructor‑based injection example:

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    @Autowire
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }
}

Setter‑based injection example:

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    @Autowire
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

Field‑based injection example:

public class UserServiceImpl implements UserService {
    @Autowire
    private UserDao userDao;
}

Although field injection is concise and widely used, it has several drawbacks:

It cannot be used with final fields because the value must be set before the constructor finishes.

It hides the single‑responsibility principle; a class with many injected fields may indicate that it does too much.

It tightly couples the class to Spring’s IoC container, making the class harder to use outside the container.

Dependencies become private fields, obscuring what the class needs and preventing early validation of null values.

Errors due to missing dependencies surface only at runtime when the bean is first used.

Example of a constructor with many parameters that may violate the single‑responsibility principle:

public class VerifyServiceImpl implements VerifyService {
    private AccountService accountService;
    private UserService userService;
    private IDService idService;
    private RoleService roleService;
    private PermissionService permissionService;
    private EnterpriseService enterpriseService;
    private EmployeeService employService;
    private TaskService taskService;
    private RedisService redisService;
    private MQService mqService;

    public VerifyServiceImpl(AccountService accountService, UserService userService, IDService idService,
                           RoleService roleService, PermissionService permissionService,
                           EnterpriseService enterpriseService, EmployeeService employService,
                           TaskService taskService, RedisService redisService, MQService mqService) {
        this.accountService = accountService;
        this.userService = userService;
        this.idService = idService;
        this.roleService = roleService;
        this.permissionService = permissionService;
        this.enterpriseService = enterpriseService;
        this.employService = employService;
        this.taskService = taskService;
        this.redisService = redisService;
        this.mqService = mqService;
    }
}

Conclusion: Avoid field injection; prefer constructor injection for mandatory dependencies to make them immutable and non‑null, and use setter injection for optional dependencies.

Postscript: This content is translated from the article “field‑injection‑is‑not‑recommended” with added personal interpretation.

Backend DevelopmentSpringdependency injectionConstructor InjectionField InjectionSetter Injection
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

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.