0

My apps commonly have one or more prop holders. These holders contain config data used in the app such as:

@Component
@ConfigurationProperties(prefix="app.orders")
@Data //lombok
public class OrderProps {

     private int maxItems;
     // other order props
}

Various components that use one or more of these props get injected with the prop holder:

@Service
public class OrderService {

    private int maxSize;

    public OrderService(OrderProps props) {
         maxSize = props.getMaxSize();
    }

 }

In this example, OrderService is only dependent on maxSize. Other classes may have also a varying number of properties needed from OrderProps.

Doesn't injecting @ConfigurationProperties classes violate the Law of Demeter. Specifically, doesn't it mask the real dependency (in this case an int) as described here?

Is there way to design without violating? Littering code with @Value("${order.maxItems}") or perhaps less problematic @Value("#{orderProps.maxItems}") seems to have its own set of problems especially when refactoring / maintenance.

2

Doesn't injecting @ConfigurationProperties classes violate the Law of Demeter. Specifically, doesn't it mask the real dependency (in this case an int) as described here?

Yes and yes. If OrderService only requires an int, then that's all you should be injecting. OrderProps is a bag of properties that only exists as a convenient injection point for Spring, and you should never design your domain classes around a specific framework.

Littering code with @Value ... seems to have its own set of problems especially when refactoring / maintenance.

This is precisely why I'm not a fan of Spring component scan for larger projects. I find it cleaner and more maintainable to limit configuration and auto-wiring responsibilities to @Configuration classes:

@Configuration
public class OrderServiceConfiguration {
    @Autowired
    private OrderProps orderProps;

    @Bean
    public OrderService orderService() {
      return new OrderService(orderProps.getMaxItems());
    }
}
  • Thanks, but what impact do we have by losing @Service annotation on OrderService? Is it only component scanning? – James Mar 5 at 18:58
  • Yes, @Service and other component annotations are just markers for component scanning (Spring javadoc). – casablanca Mar 6 at 7:19
  • Thanks. This post and the Spring reference doc indicate that other benefits of using @Service is clearly marking the intent of the class, ease of targeting pointcuts, possible tool integration and that @Service may carry additional semantics in future releases. So, I suppose it's a trade-off between those benefits vs not violating the Law of Demeter. – James Mar 6 at 15:56
  • Note that anything you can do with @Service, you can also do externally via a configuration class. The service annotation might be a tad bit simpler but the trade-off is that you couple your classes to Spring. – casablanca Mar 7 at 5:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.