Using Lombok @RequiredArgsConstructor to Reduce @Autowired Boilerplate in Spring Services
This article explains how Lombok's @RequiredArgsConstructor can replace repetitive @Autowired field injections in Spring services by generating a constructor for final fields, demonstrates the underlying annotation‑processing mechanism, and provides practical code examples for applying this technique in backend Java projects.
In typical Spring development the @Autowire annotation is used frequently to inject dependencies, often resulting in many repeated annotations within a class. When a class has dozens of such fields, the code becomes verbose and harder to maintain.
The solution is to use Lombok's @RequiredArgsConstructor annotation, which automatically generates a constructor for all final fields, allowing Spring to perform constructor injection instead of field injection.
What is @RequiredArgsConstructor? It is a Lombok annotation that creates a constructor containing parameters for every field marked final . The generated constructor ensures that these immutable fields are properly initialized at object creation.
public class ExamplePo {
private final String name;
private final int age;
private String nameCode;
public static void main(String[] args) {
ExamplePo examplePo = new ExamplePo("name", 12);
}
}In the Main method, the constructor generated by @RequiredArgsConstructor is used to create an ExamplePo instance, initializing only the final fields name and age . Non‑final fields like nameCode are not included in the constructor.
To understand how Lombok implements this, the article shows a custom annotation processor that mimics Lombok's behavior. The processor scans classes annotated with a custom @MyRequiredArgsConstructor , collects all fields, and generates a public constructor that assigns each field.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface MyRequiredArgsConstructor {
boolean includeAllFields() default false;
} @SupportedAnnotationTypes("com.example.annotation.MyRequiredArgsConstructor")
public class MyRequiredArgsConstructorProcessor extends AbstractProcessor {
@Override
public boolean process(Set
annotations, RoundEnvironment roundEnv) {
// Iterate classes, collect fields, generate constructor, write source file
return true;
}
}Applying this concept to Spring, the article refactors a typical UserService class by adding @RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired}) and declaring the mapper and service fields as private final . Lombok then generates a constructor annotated with @Autowired and @Lazy , eliminating the need for multiple field‑level @Autowire annotations.
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
public class UserService {
private final XxxMapper xxxMapper;
private final Xxx1Mapper xxx1Mapper;
private final XxxService xxxService;
// ... other fields
}The onConstructor_ attribute allows additional annotations to be placed on the generated constructor, which is useful for handling circular dependencies via @Lazy . When Spring encounters @Lazy , it creates a proxy instead of an immediate bean instance, deferring actual instantiation until the bean is first accessed.
In summary, by leveraging Lombok's @RequiredArgsConstructor with constructor injection, developers can significantly reduce boilerplate @Autowire usage, improve code readability, and maintain immutable dependencies in backend Java applications.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
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.