• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

When and Why use Spring? What are the advantages.

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As a Junior Java Developer, I've been encouraged to use Spring from the get-go.
However, so far I've seen many problems in using Spring, and not so many of the advantages.

Here are the drawbacks I've found:

- Using Spring, regular compile-time checking is disabled.

You can't use proper type-checking with getObject, you simply have to cast the result to what you expect, and risk a run-time cast exception.
I'm also not entirely sure why Spring isn't able to use the method many mocking frameworks use, and accept the expected class as an argument to avoid casts.

- Part of your application is now written/specified in XML, so many static checking tools can no longer operate on your code without specific support for spring.

This also means requiring things like strings of fully qualified classnames, that IDEs like eclipse can't automatically update or re-factor when a class is renamed or moved.

- classes written for spring need to be adapted for spring, and so do many libraries.

Using things easily with spring-support often requires a specific spring-version of that package. Using spring components outside of spring is difficult, and often classes written
for spring require refactoring to work as regular pojos again.

- exceptions are very verbose, and often unhelpful

For adding a plumbing framework on top of your code, you get exposed to a lot of the complexity whenever something goes wrong.
It's not unusually for an exception message to list *every* bean that failed to initialise.
Things like invalid XML, won't be reported as such (perhaps with a filename and line number), but rather with the failure of some kind of abstract class responsible for parsing the XML.

It's possible that I've picked up some mis-conceptions about Spring, but if this is that case, I'd certainly like those cleared up too.
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It does seem like you've mentioned a lot of problems you might encounter if you use Spring in a suboptimal way. I'll try to address some now and we can go through the others later in greater detail, maybe with more concrete code examples.

Using Spring, regular compile-time checking is disabled


I don't quite understand where this is coming from. Are you referring to the fact that there's no way for the compiler to check whether the "class" attribute in a bean declaration is actually correct and assignment-compatible with the parameters of constructors and methods into which the bean can be injected? I don't find this to be a big problem, especially since I do test-driven development and I use an integration test to verify that my configuration is set up correctly. Newer versions of Spring also allow you to do annotation-based configuration to greatly reduce, if not eliminate, the need for XML-based configuration. Sounds like you may not be taking advantage of the annotations or maybe you're using an older version that only supports XML-based configs.

You can't use proper type-checking with getObject, you simply have to cast the result to what you expect, and risk a run-time cast exception.
I'm also not entirely sure why Spring isn't able to use the method many mocking frameworks use, and accept the expected class as an argument to avoid casts.


Now it really is starting to sound like you're using an older version of Spring. As of Spring 3.0, you should be able to specify the expectedType when you call the getBean() method. See http://static.springsource.org/spring/docs/3.0.x/javadoc-api/index.html?org/springframework/beans/factory/FactoryBean.html

Also, you should not have to call the getBean() method very often anyway, if at all. I only use it in (hopefully) rare situations where it's difficult or impossible to use Spring dependency injection (most likely because of hard-to-refactor legacy code and poor design) so you have to resort to dependency lookup instead. If you find yourself using dependency lookup more often than you use dependency injection then the design of your application and your use of Spring with it is suboptimal.
 
Chelsea Hannover
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
> Using Spring, regular compile-time checking is disabled

This is more a heading to the paragraph below it, but it *is* the class checking that I'm referring to.
A bad XML config can mess this up, and rather than get "Wrong class type for bean" from spring, you will get a class cast exception from your app.
If the class can now be specified, then ignore this point.

While I can't recall the details exactly, I believe a past experience with spring annotatons put me off them, something about their flexibility compared to XML.
What would you say spring annotations/xml offer over, say, a manager class/java package with explicit logic for dependancy injection?

Is there a way to specify to spring that an autowired field *mustn't* be null? i.e. if the intended-to-wire bean failed to initialise.
It seems I have to do this null-check myself otherwise.
If spring could do this check, then maybe it could also implement some kind of backup-behaviour?

> Also, you should not have to call the getBean() method very often anyway

What does injection offer over lookup?


Thanks for your reply.
 
Rancher
Posts: 2759
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Using Spring, regular compile-time checking is disabled.
You do have a type safe way of getting beans Just use getBean method that takes class as parameter

Part of your application is now written/specified in XML, so many static checking tools can no longer operate on your code without specific support for spring.
That will happen with any framework that provides IoC. That's a disadvantage of the IoC pattern, not the framework that implements it. The advantage of IoC is that it forces you to decouple modules from each other, and forces you to build to interface

classes written for spring need to be adapted for spring, and so do many libraries.
Not really. Classes don;t have to be dependent on spring for spring to instantite them and inject dependencies. Using spring makes it easier. It's not required

---------------------------------------------------------------------------

Since, you are limiting your post to spring core, I will too. Spring core basically gives you 2 things
a) Dependency Injection
b) Aspect Oriented Programming (AOP)


DI basically lets you make classes independent of each other, and it (almost) eliminates the need for Factory classes. Using DI, classes talk to each other through the interfaces. The framework injects instances of the classes into each other.
AOP allows you to build aspects. Aspects are code that provide cross-cutting functionality (for example, transaction management). This allows you to reduce the code in your class by moving boilerplate code into aspects

I won;t go into too many details in the post, and I will encourage you to pick up a book. I've found Spring In Action to be most benificial is demystifying Spring.

 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have to make a correction/clarification to the statement that "DI lets you make classes independent of each other" -- any class that refers to another class is dependent on that class. Only when there are no direct or indirect references in either class to the other can you say that they are independent of each other.

That said, dependency injection separates the concerns of creating an object and using an object. By separating these concerns, you loosen the coupling between the two classes. If a class that uses another is also responsible for obtaining a reference to it, as would be the case when you use dependency lookup, coupling is tighter. On the other hand, if an object can safely assume that it has a valid reference to another object and doesn't concern itself with how that reference is obtained beyond providing a way for it to be injected, then the coupling is much looser. Loose coupling is a cornerstone of flexible designs so the more of it that you have, the better.
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To explain in code:


The difference is subtle but B is more tightly coupled to Foo than A is to Foo because B creates its own Foo whereas A just doesn't try to do that, it lets someone else worry about object creation. If you're still not convinced that the coupling is looser with A, imagine what you'd need to do to test A with a different implementation of Foo. Now what would you need to do to test B with a different implementation of Foo?
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
BTW, dependency lookup only increases coupling even more because now the class doing the lookup is also dependent on the lookup service as well. In the case of Spring, if you use dependency injection, your POJOs aren't even aware that they are in the Spring environment. If you use Spring dependency lookup, you will couple your POJO to the Spring BeanFactory or ApplicationContext class. Always prefer DI over DL.
 
Chelsea Hannover
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry for the delay, had to do a lot of travelling recently.

>> classes written for spring need to be adapted for spring, and so do many libraries.
> Not really. Classes don;t have to be dependent on spring for spring to instantiate them and inject dependencies. Using spring makes it easier. It's not required

> your POJOs aren't even aware that they are in the Spring environment

Would you recommend constructor and/or setter-methods for DI?
Because surely auto-wiring does introduce a Spring dependency?

 
Jayesh A Lalwani
Rancher
Posts: 2759
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Chelsea Hannover wrote:

Would you recommend constructor and/or setter-methods for DI?



I'm agnostic wrt to the whole setter injection vs constructor injectin debate. Spring provides both ways because they wanted users to be able to instantiate any classes, even if the users didn't create the classes themselves. Just remember that for your own classes
a) All initialization code should be in the Init method, not the constructor
b) Be consistent. DOn;t use constructor injection in one place and setter injection in another place. It makes it confusing

Chelsea Hannover wrote:

Because surely auto-wiring does introduce a Spring dependency?


Spring supports Java annotations. So, even if you use autowiring, you don't need to add a dependency on Spring if you use Java annotations. If you are using those annotations, you will always need A container. Spring just provides a convenient lightweight container that you can use anywhere.
 
reply
    Bookmark Topic Watch Topic
  • New Topic