4

I am writing software for many years now and always tried to create expressive, clearly readable, maintainable, robust code. Recently I joined a team developing web apps using Spring managed objects. But I feel very uncomfortable with that technology. For me, it feels like all encapsulation and information hiding principles, achievements of decades of software engineering, were just abandoned. I clearly can see the pros of using an Inversion of Control container, for moving system dependencies out of program code into configuration files. But now, I see Spring used in ways that, I feel, are just adding an unnecessary bunch of complexity without producing any benefit.

Using Spring for the creation of webapp backing beans, objects are no longer clearly organized in modules and no longer have smallest possible visibility. Instead, there is now a single, global space of bean names. Because of that, objects tend to get awful names like 'pendingOrderCustomerName' and, to make things worse, such names do not even clearly identify a well-defined entity, because bean definitions can come from various definition sources, gathered from openly specified locations: Instead of being defined simply as a class in a package, Spring beans are assembled from xml files, with free overriding possibilities and loosely defined relationships.

For example, when I have a type "Account" in plain java, in the package "my.webstore", I can usually know about properties, relationships and abilities of that type in a single place, the "my/webstore/Account.java" file. Instances of "Account" exist as references in objects working with accounts, the state of any instance is exactly defined by the class. With Spring beans, however, things get more complicated: An instance of "Account" now exists under a global name, in a container-managed scope, having a state being assembled from xml files, found along a file search path based on naming patterns...

Gone the days when, to understand what an object does and how it behaves, you just had to read its program source. Today, you need the object's java source (which may be complex enough to understand), plus you have to find any configuration files that might alter that object, which is not easy because you have to find out all the ways where configurations might come from and you have to find out in which order they override each other

Maybe it's just a matter of taste, but I also wonder why people prefer the verbose, clumsy xml syntax, as in:

  <bean id="p1" class="Point" scope="prototype">
    <property name="x">
      <value>20</value>
    </property>
    <property name="y">
      <value>80</value>
    </property>
  </bean>

over this:

  p1 = new Point(20,80);

This example may seem exaggerated, but I tell you I have seen worse!

It is not my intent to criticize the Spring framework by itself, it is very strong and an excellent ingredient in many cases. My concerns are about how to prevent misuse, how to keep maintainability, how to guarantee quality and stability, how to find dependencies, how to document code... what is your experience?

Markus
  • 668
  • 7
  • 27
  • 2
    "What is your experience" is not a clearly defined question with a recognizably correct answer. How will you mark an answer as correct? Please ask your question more clearly so we know what you're looking for. I can maybe infer some questions like "How do you navigate dependencies in a dependency injection framework?" or "What are the current best practices for organizing spring-managed components?" – Jason Jun 03 '13 at 12:18
  • The purpose of my question isn't to be an offer for answer points – Markus Jun 05 '13 at 07:13
  • Thank you for clarifying that you do not intend to mark answers as correct. – Jason Jun 06 '13 at 12:29

2 Answers2

2

As you have seen, it's quite easy to misuse Spring if you don't understand properly the principles of object-oriented design. The Spring IoC container (let's forget about the rest for now, as there is a huge portfolio of libraries under the Spring umbrella) really shines when you use it to:

  • define a component model (e.g. controllers, services, repositories and their dependencies)
  • centralize component dependency lookup (e.g. replace your service locators, JNDI lookups or other stateless component retrieval strategies)
  • decorate components with technical aspects (e.g. transaction management, cacheing, access control, etc.)

Spring, or any IoC container, will allow you to have a uniform component model, remove a lot of boilerplate code, and isolate cross-cutting concerns into centralized aspects. It should also push you in implementing a system made of loosely coupled components focusing on implementing business logic, something that will improve readability, testability and maintainability in the long run.

For sure, you will not gain anything (and actually lose a lot) if you start defining Accounts and Points as Spring components. These should still be designed as entities or value objects. They should still be part of the proper package and appropriate visibility modifiers should be applied. They should still be instantiated, manipulated and managed with the strategies you would use if your application hadn't leveraged an IoC container.

It looks like you already know sound design principles, so I would encourage you to trust your instincts on this. If a class is a reusable (and often stateless) component, then declare it as a Spring component and inject it where it's appropriate. If you're not sure, leave it as a normal, unmanaged class and use it normally. You will come to see where it makes sense to declare components and where it doesn't.

I also encourage you to research how to leverage @Component and <context:component-scan> declarations to reduce the XML footprint.

Good luck.

Spiff
  • 2,266
  • 23
  • 36
0

Many features of Spring get misused. I used to think just like you but recently when I understood more of Spring I'm starting to like it, altough any dependency injection framework would do and I'd probably prefer Guice over Spring if I got the choice.

The issue seems to be that people know how to use Spring but not why. Especially when not to use it. Spring beans are useful when you have multiple implementations. This is where dependency injection shines. In your example, I certainly hope that Point doesn't have any other implementations, and thus it's Spring misused once again.

For me, Guice motivation motivated me to understand more about dependency injection, it applies equally well to Spring.

That said, you could checkout Spring's annotations to see how your configuration and code can be kept in one place.

jontejj
  • 2,800
  • 1
  • 25
  • 27