View Poll Results: How do you ensure required dependencies are set?

Voters
243. You may not vote on this poll
  • 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.
Page 1 of 7 123 ... LastLast
Results 1 to 10 of 67

Thread: How do you ensure required dependencies are set?

  1. #1
    Join Date
    Aug 2004
    Location
    Amsterdam, Netherlands
    Posts
    450

    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;
    	}
    }
    Last edited by Alef Arendsen; Jun 8th, 2007 at 10:17 AM. Reason: Tidying layout
    Alef Arendsen
    SpringSource
    http://www.springsource.com

  2. #2

    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.

  3. #3
    Join Date
    Feb 2005
    Posts
    217

    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?

  4. #4
    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

  5. #5
    Join Date
    Feb 2005
    Posts
    217

    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.

  6. #6
    Join Date
    Aug 2004
    Location
    Amsterdam, Netherlands
    Posts
    450

    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

  7. #7
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    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.

  8. #8
    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!

  9. #9
    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.

  10. #10
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •