spring @Autowire property vs setter

What is the difference between anotate @Autowired to a property or do it in the setter?

As far as I know they both have the same result, but is there any reason to use one over the other?

UPDATE (to be more concise)

Is there a difference between this

package com.tutorialspoint;

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

public class TextEditor {
   private SpellChecker spellChecker;

   @Autowired
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }

   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

and this

package com.tutorialspoint;

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

public class TextEditor {
   @Autowired
   private SpellChecker spellChecker;

   public TextEditor() {
      System.out.println("Inside TextEditor constructor." );
   }

   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

Solution 1:

Sometimes you need an instance of class A, but you do not store A in the fields of the class.
You just need A instance to perform a one-shot operation. Or, you use A instance to obtain an instance of B, and you are storing B in the field.

In those cases, a setter (or constructor) autowire will suit you better.
You will not have unused class-level fields.

Concrete example:
You need to construct RabbitTemplate (an object that sends messages to RabbitMQ) To construct it, you need ConnectionFactory
http://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/rabbit/core/RabbitTemplate.html#RabbitTemplate-org.springframework.amqp.rabbit.connection.ConnectionFactory-

You do not need to store that ConnectionFactory. In that case, code that looks like this:

Class MyClass {
private RabbitTemplate template;

@Autowired 
void setConnectionFactory(ConnectionFactory c) {
    template=new RabbitTemplate(c);
}
}

...will serve you better than directly autowiring the ConnectionFactory field.

In this example, autowiring at the constructor level would be even better, because your object will always be completely constructed. It will be clear that ConnectionFactory is a mandatory dependency, not an optional one.

Solution 2:

With @Autowired annotation, you don't need a setter method. Once your bean's constructor is done with allocating/creating the object, Spring will scan for this annotation and would inject the object instances that you annotated.

While if you have setter and if you are still using xml config, you would explicitly set properties.

Having said that, You could annotate your constructor and setter method with autowired annotation which i would prefer as this would give me flexibility later on to move away from Spring (although i wont do it).

Solution 3:

If you use @Autowired annotation on a property, spring will initiate the property using spring.xml. You don't need setter in this case.

If you use @Autowired annotation on a setter, you are specifying to spring that it should initiate this property using this setter method where you can add your custom code, like initializing some other property with this property.

Usage with Example: In the case of using DAO operations using JdbcTemplate, you need DataSource as an input to JdbcTemplate, but DataSource is not required as a property in itself. So you can use DataSource Setter to initialize JdbcTempate by auto-wiring DataSource Setter. Please see the below code:

class DaoDemo{
   //@Autowired
   //private DataSource dataSource;
   private JdbcTemplate jdbcTemplate;

   @Autowired
   public void setDataSource(DataSource dataSource){
     //this.dataSource = dataSource;  
     this.jdbcTemplate = new JdbcTemplate(dataSource);
   }

   public int getTableRowCount(){
      String sql = "SELECT COUNT(*) FROM DEMOTABLE";
      //jdbcTemplate.setDataSource(dataSource);    //No need to do this as its done in DataSource Setter now.
      return jdbcTemplate.queryForObject(sql,Integer.class);

}

In the above code, the only use of dataSource was to get passed in JdbcTemplate. So, creating a property of dataSource doesn't make sense here. So, just use the @Autowired on setter method of DataSource bean to get its entry from spring.xml and make use of it at that particular time itself.