Community   SpringSource   Projects    Downloads    Documentation    Forums    Training   Exchange   Blogs

Go Back   Spring Community Forums > Core Spring Projects > Core Container

View Poll Results: How do you ensure required dependencies are set?
By using the dependency-check attribute in XML 28 11.52%
By using the @Required annotation (or a custom annotation) 52 21.40%
By using InitializingBean and an assert facility 58 23.87%
By using init-method and an assert facility 35 14.40%
I don't have to, because I use constructor injection for required properties 47 19.34%
I check my dependencies in my business methods 18 7.41%
I don't check required dependencies 83 34.16%
Multiple Choice Poll. Voters: 243. You may not vote on this poll

Reply
 
Thread Tools Display Modes
  #1  
Old Mar 10th, 2007, 03:26 AM
Alef Arendsen Alef Arendsen is offline
Senior Member
Spring Team
 
Join Date: Aug 2004
Location: Amsterdam, Netherlands
Posts: 451
Default How do you ensure required dependencies are set?

-- THIS POLL HAS BEEN CLOSED. FUTURE POLLS WILL TAKE PLACE ON WWW.SPRINGFRAMEWORK.ORG --

To get a feel for what parts of the Spring Framework you're using, from now on, we will be hosting a series of polls on the forum. Each poll will not only ask you a very simple (multiple choice) question, but also give you some insight into the techniques the poll is about. This is the first poll. Future polls can be found through the central polls page. If you have a good idea for a poll, just send me a private message. Discussions about the poll itself can be done in the comments of course.

Last but not least, we very much value your feedback and will be using all of it throughout the further development of the Spring Framework. So we appreciate it a lot if you could take the time to fill out this poll!

thanks!
Alef

More information for poll - how do you verify if dependencies are set?

Using the dependency-check attribute in Spring XML
From the beginning, Spring has features a dependency checking mechanism you could enable in the XML format. The following example will trigger an Exception upon loading the application context:

Code:
package com.interface21;

public class Service {

	private Helper helper;

	public void setHelper(Helper helper) {
		this.helper = helper;
	}
}

package com.interface21;

public class Service {

	private Helper helper;

	public void setHelper(Helper helper) {
		this.helper = helper;
	}
}

<bean class="com.interface21.Service" dependency-check="objects"/>
The dependency checking attribute can be set for objects, simple properties or both. The default for Spring is to not enable dependency checking. More information on the dependency checking mechanism can be found in chapter 3 of the reference manual. Dependency checking works by inspecting the class that is configured. For all setters, the configuration is inspected. If a certain property does not have a matching configuration in XML, an Exception is thrown and the loading of the ApplicationContext does not proceed.

Using the @Required annotation
In Spring we introduced a way to check dependencies using an annotation. By simple adding the @Required annotation to a setter in your class. The difference with the attribute (see above) is that you don't mention it in the XML file(s), but in your Java classes. Enabling dependency checking using the @Required annotation, you have to install a BeanPostProcessor. So the configuration below for how to do this. By default, Spring uses the [font-courier]org.springframework.beans.factory.annnotation.Requ ired[/font] annotation. If you don't want to tie your code to Spring (which in general is a good idea anyway, you can use your own annotation, by configuring the RequiredAnnotationBeanPostProcessor. More information on the @Required annotation can be found in the reference manual.

Code:
package com.interface21;

import org.springframework.beans.factory.annotation.Required;

public class Service implements InitializingBean {

	private Helper helper;	

	@Required
	public void setHelper(Helper helper) {
		this.helper = helper;
	}
}

<bean class="com.interface21.Service"/>
	
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>

<!-- or, if you want to use your own annotation -->
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
    <property name="requiredAnnotationType" value="com.mycompany.MyAnnotation"/>
</bean>
Using InitializingBean or init-method (and possibly Spring's Assert class)
Another way of checking dependencies is to use either Spring's InitializingBean interface or a custom init-method. Both features are thoroughly explained in the reference manual. Using either Spring's Assert class or the Java assert keyword, you can make sure arguments are set correctly. The example below shows using the InitializingBean.

Code:
package com.interface21;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

public class Service implements InitializingBean {

	private Helper helper;

	public void afterPropertiesSet() throws Exception {
		Assert.notNull(helper, "Helper should not be null");
	}

	public void setHelper(Helper helper) {
		this.helper = helper;
	}
}
Using constructor injection
Spring features two types of dependency injection: setter injection and constructor injection. Both have their respective differences, but one pro of constructor injection is that objects can never be instantiated in an invalid state. So one (also very clean) way of ensuring required dependencies are set is using constructor injection such as in the example below. Spring by the way has always featured constructor injection (from the first final release that is). Because Spring first implemented setter injection and got to doing constructor injection only until later in the development process, lots of examples from the early beginning are using setter injection and it is sometimes being regarded as the Spring-recommended way of doing DI. This is definitely not the case. Many of us are using constructor injection and prefer it over setter injection for required properties. More information on constructor and setter injection can be found in chapter 3 of the reference manual.

Code:
package com.interface21;

public class Service {

	private Helper helper;

	public Service(Helper helper) {
		this.helper = helper;
	}
}
__________________
Alef Arendsen
SpringSource
http://www.springsource.com

Last edited by Alef Arendsen; Jun 8th, 2007 at 10:17 AM. Reason: Tidying layout
Reply With Quote
  #2  
Old Mar 12th, 2007, 05:10 PM
peter@mxgroup.net peter@mxgroup.net is offline
Junior Member
 
Join Date: Aug 2004
Posts: 4
Default

G'day Alef,

Your survey prompted this comment.....

I've always found that the one setup I would really like is not available. i.e. a dependency-check on the bean [annotation on the class e.g. @dependency_check(ElementType.Object) ], with an @optional annotation on the setter, for the rare occasion an object isn't injected.

The problem with @REQUIRED to me is it fails the DRY test. Perhaps at a class level I should be able to say my default behavior is(not required) and I mark the required setters , or say my default behaviour (required) and mark optional setters.

Anyway, it's a small gripe, on an otherwise most useful service..
--------------

package com.interface21;

@dependency_check(ElementType.OBJECT)
public class Service {


private Helper helper;

private Foo foo;

public void setHelper(Helper helper) {
this.helper = helper;
}

@OPTIONAL
public void setLocalFoo(Foo foo) {
this.foo = foo;
}

<bean class="com.interface21.Service" />
-----
Best Rgds, peter h.
Reply With Quote
  #3  
Old Mar 12th, 2007, 06:20 PM
cwilkes cwilkes is offline
Senior Member
 
Join Date: Feb 2005
Posts: 214
Default Like @required but not in the springframework namespace

I really like the idea of @required as then I don't have to do an init-method that checks for it, however I don't like the idea of introducing something that depends on spring when it doesn't have to.

Are there any generic (ie java.*) annotations that are like @required? I suppose I could make my own, like I do for the init-method. Is there support in Spring to use different annotation names for this goal?
Reply With Quote
  #4  
Old Mar 12th, 2007, 10:26 PM
manifoldronin manifoldronin is offline
Senior Member
 
Join Date: Oct 2004
Location: Herndon, VA, US
Posts: 648
Default

I usually leave it to the test cases. A missing required injection is usually not a subtle error and should blow up pretty quickly with a NullPointerException under any decent test coverage.
__________________
--Jing Xue
Reply With Quote
  #5  
Old Mar 12th, 2007, 10:45 PM
cwilkes cwilkes is offline
Senior Member
 
Join Date: Feb 2005
Posts: 214
Default

Quote:
Originally Posted by cwilkes View Post
Are there any generic (ie java.*) annotations that are like @required?
I should of RTFM'ed first, this is answered in the above post linking to http://www.springframework.org/docs/...tions-required . Look for the @Mandatory description.
Reply With Quote
  #6  
Old Mar 13th, 2007, 03:19 AM
Alef Arendsen Alef Arendsen is offline
Senior Member
Spring Team
 
Join Date: Aug 2004
Location: Amsterdam, Netherlands
Posts: 451
Default

Quote:
Originally Posted by peter@mxgroup.net View Post
G'day Alef,
I've always found that the one setup I would really like is not available. i.e. a dependency-check on the bean [annotation on the class e.g. @dependency_check(ElementType.Object) ], with an @optional annotation on the setter, for the rare occasion an object isn't injected.
Maybe this is not such a bad idea in some form or another. I've added a JIRA issue that describes this request:

http://opensource.atlassian.com/proj...rowse/SPR-3252
__________________
Alef Arendsen
SpringSource
http://www.springsource.com
Reply With Quote
  #7  
Old Mar 13th, 2007, 03:40 AM
Alarmnummer Alarmnummer is offline
Senior Member
 
Join Date: Nov 2004
Location: Hilversum - The Netherlands
Posts: 1,053
Default

I prefer using constructor based DI (with final fields) because it prevents visibility problems (you don't depend on the appcontext) and it also makes components easier to understand (my opinion). And yes, beans with large amount of properties suck bigtime. I wish Java had named arguments, named constructors and a better way to deal with default argument values. This would fix a lot of problems.
__________________
blog: http://pveentjer.wordpress.com project: STM Implementation http://multiverse.googlecode.com
Reply With Quote
  #8  
Old Mar 13th, 2007, 04:07 AM
belugabob belugabob is offline
Senior Member
 
Join Date: May 2006
Location: Crawley, UK
Posts: 105
Smile

I'm not checking for required dependencies at the moment, although it's been niggling away at the back of my brain for some time now.
I have implemented a system which warns me (on the login page) if I have any Struts actions which are not defined as Spring beans. This catches misconfigurations early in the cycle, but doesn't warn me about unfulfilled dependencies.

This poll has given me the incentive to look at the situation further, my initial thoughts being ...
  1. I'd probably favour constructor injection, where possible, as I prefer to have objects that are correctly configured by the end of the construction phase. (This will probably be more feasible when I move away from Struts1.x)
  2. The annotation method is interesting - definitely need to minimise coupling to Spring
  3. I tend to agree with manifoldronin - a correct amount of tests should reveal most, if not all, of unfulfilled dependencies.

Thanks for the nudge.
__________________
If you didn't learn anything today, you weren't paying attention!
Reply With Quote
  #9  
Old Mar 13th, 2007, 10:06 AM
airwave209 airwave209 is offline
Junior Member
 
Join Date: Mar 2005
Location: Hong Kong
Posts: 19
Default

My choices are rather funny... some implements InitializingBean, some use constructor injection, some doesn't.

At one of the legacy projects I was working the codes and configurations are simply chaotic: all 3 methods are used. But at the other project which I'm currently working on I use autowiring by name with zero dependency checking.

I also prefer using JUnit integration tests to see if component dependencies are satisified in the XMLs.
Reply With Quote
  #10  
Old Mar 13th, 2007, 12:39 PM
karldmoore karldmoore is offline
Senior Member
 
Join Date: Sep 2006
Posts: 8,425
Default

Quote:
Originally Posted by Alarmnummer View Post
I prefer using constructor based DI (with final fields) because it prevents visibility problems (you don't depend on the appcontext) and it also makes components easier to understand (my opinion). And yes, beans with large amount of properties suck bigtime. I wish Java had named arguments, named constructors and a better way to deal with default argument values. This would fix a lot of problems.
It's interesting how people prefer immutable objects but most people I know use setter based injection.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 08:06 AM.


Contegix provides first-class managed hosting and partial sponsorship of these forums.

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.