Search code examples
javaspringdependency-injection

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

  • Sometimes you need an instance of class A, but you do not store A in the fields of the class that uses A.
    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.