Lives in the UK. Likes blogging, cycling and eating lemon drizzle cake. Roger is a DZone MVB and is not an employee of DZone and has posted 143 posts at DZone. You can read more from them at their website. View Full User Profile

Using Spring’s @Required Annotation

10.07.2011
| 8482 views |
  • submit to reddit

When your application needs a bean class, it’s not unusual for certain attributes to be mandatory, which if missed from your Spring config file will cause you problems at some undetermined future time. The Guys at Spring thought of this and came up with the @Required annotation that you can apply to your bean’s setter method:

  // Snippet from a plain old bean...
  private int id;
  private String street1;

  @Required
  public void setId(int id) {
    this.id = id;
  }

  @Required
  public void setStreet1(String street1) {
    this.street1 = street1;
  }


...together with the following addition to your Spring configuration file:

<!-- Switch on the required annotation  -->
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>

...which gets Spring to check at load time that your Setter method has been called and throwing a org.springframework.beans.factory.BeanInitializationException if you forget setup your bean correctly.

I personally prefer to use constructor args to initialize beans with mandatory parameters, providing that there aren’t too many of them. There are at least two benefits here: firstly you don’t need to mess around with @Required annotations because if you have a missing constructor argument you’ll know about it and secondly, initializing beans using constructor args means that its attributes can be marked as final, which improves thread safety.

There is one proviso here. Using constructor args is only okay if your bean is not being used by some API that expects your bean to have Setter methods. In this case you’ve no choice and @Required is a good idea.

 

From http://www.captaindebug.com/2011/09/using-springs-required-annotation.html

Published at DZone with permission of Roger Hughes, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

matt inger replied on Sat, 2011/10/08 - 9:39am

In related news, coming to EJB v5, an innovate new annotation javax.ejb.Required. At what point does Oracle give up on EJB and just let Spring, Seam and Hibernate serve as the standards? All EJB has become is abstraction over what those products offer. An abstraction which proves to be much more complicated, and much less powerful.

Cristian Vasile... replied on Sat, 2011/10/08 - 9:38pm

Constructor injection should be preferred.

You  get compile-time checking for required dependencies and it works without Spring too.

This way, you follow the principle that an object should be initialized and ready for use as soon as the constructor finishes executing.

 

I always use constructor injection for required dependencies.

Sylvain Brocard replied on Wed, 2011/10/12 - 9:21am

I have wonder several time if I should use constructor with arguments or setters and I still prefer to use setters with @Required.

I do also think it's important to have object ready once it gets build but if you do use XML configuration I found it quite annoying because you loose the advantage of Java Beans. I found it easier with setters because you have named properties and it becomes simpler with Spring IDE to configure your beans (Ctrl+Space on Eclipse on your XML configuration file let you find what properties you can set and it will also check for invalid properties name) and I found it more readable (see example below).

Even with a constructor, if you configuration file is wrong you will known only at load time like setters. If I remember well Spring IDE can detect it at compile time when the constructor does not exist but I think they could implement the same thing with @Required.

<bean class="x.y.ConstructorClass">
  <constructor-arg index="0" value="10000" />
  <constructor-arg index="1" value="20000" /> 
</bean>

<bean class="x.y.JavaBeansClass">
  <property name="connectionTimeoutMs" value="10000" />
  <property name="readTimeoutMs" value="20000"  />
</bean>

Roger Hughes replied on Wed, 2011/10/12 - 10:40am in response to: Sylvain Brocard

It's a matter of choice as to whether or not you prefer setters or constructor arguments. I prefer constructor args simply because they're thread safe and from experience, thread safe code is more robust. As you say, using setters does mean that you have named properties, which is easier to read. For more information see Thread-Safe Immutable Objects.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.