What basic recommendations for designing a Spring component?
Main purposes:
- avoid NullPointerExceptions
- flexibility for unit-testing
- thread-safety
IMHO (based on Spring 4 official doc https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/beans.html#beans-constructor-injection (“constructor-based or setter-based DI?”)):
- Optional fields should have default values. If required they should have annotations @Value (for simple types like int, String, etc) or @Autowired for complex objects.
- Required fields should be final and declared in a sole contsructor with @Autowired annotation. If number of required fields more than 5, it is recommended to redesign classes. Every parameter in the constructor should be annotated with @Nonnull (e.g. javax.annotation.Nonnull) with null-checks inside.
- (?) Set methods are not recommended. Though for unit-testing you can add some (but maybe better to add this field to constructor). Also, @Nonnull and null-checks should be used.
- (?) Get methods are not recommended as well (why to open transitive access for internal fields?)
Example:
@Controller
@RequestMapping("/api/clients")
public final class ClientApiController {
    // optional field with a default value (simple type)
    @Value("${random.string.size}")
    private final int randomStringSize = 256;
    // optional field with a default value (complex type)
    @Autowired
    private final Charset defaultCharset = Charset.forName("UTF-8");
    // required field
    private final ClientService clientService;
    // sole constructor with required fields and NULL check
    @Autowired
    public ClientApiController(@Nonnull ClientService clientService) {
        Objects.requireNonNull(clientService, "clientService is null");
        this.clientService = clientService;
    }
    // no Set and Get methods
}
 
     
    