2

I know a lot had been written about @Autowired and @Required annotations.

But I have a very basic question as below -

What is the difference between the below two mechanism of setter injection.

I haven't yet got a complete satisafactory answer for this.

The reason is :

1)@Autowired without any extra information like - @Autowired(required=false) is same as @Required

2)What are we gaining from @Required additionally ?

3)Why @Required is recommend over @Autowired on setter injection ?

class MyClass {

   private MyService myService;

   @Autowired
   public void setMyService(MyService val) {
       this.myService = val;
   }
}


class MyClass {

   private MyService myService;

   @Required
   public void setMyService(MyService val) {
       this.myService = val;
   }
}
watchme
  • 720
  • 1
  • 9
  • 25
Atul
  • 1,560
  • 5
  • 30
  • 75
  • I think you find at least part of your answer here [https://stackoverflow.com/questions/18884670/autowired-vs-required-on-setter](https://stackoverflow.com/questions/18884670/autowired-vs-required-on-setter) – Marco Schoolenberg Apr 02 '18 at 13:03
  • Yes. I have already visited this link. The question still remains : what additional Required annotation gives which Autowired annotation cannot on setter injection ? – Atul Apr 02 '18 at 13:07
  • isn't this the answer: https://stackoverflow.com/a/18887438/669408 you are looking for? @Aurowired not limited to setters but can be used with constructor as well. – Marco Schoolenberg Apr 22 '18 at 20:19

2 Answers2

2

@Autowired is not the same as @Required.

The @Required-Annotation is specialized for telling Spring that this property has to be injected by the information given in the XML-configuration-file (eager) and not through annotations. And that doesn't matter when you use the @Autowire-Annotation.

The @Autowire-Annotation (as in your code-example), tells the ApplicationContext (a.k.a the Spring-IoC-Containter) to inject the desired dependency. (No matter how, if its by using annotations or the XML-File of the ApplicationContext).

The @Required-Annotation, tells the ApplicationContext that this property has to be mentioned in the XML-file (The XML-File of the ApplicationContext), but the Annotation on its own doesn't tell to inject the dependency. So it is used to check if it is in the XML-configuration file, but not to inject a dependency. The injection is done because the property is mentioned in the XML-file.

So in the end it tells that the injection has to be done because of a configuration in the XML-File. But again: The annotation doesn't tell that the dependency has to be injected, but that it has to be mentioned in the XML-File - which then lets the dependency be injected.

With mentioning the property in a XML-File I mean such a configuration for instance:

<bean id="MyClass" class="com.myclasses.common.MyClass">
     <property name="someProperty" value="ValueThatHasToBeInjected" />
</bean>

So why should I use it over the @Autowired-Annotation?

You should use it when the dependency has to be injected due to the informatoin given in the XML-configuration file.

Can you give me an example?

Well, there is already a very good example on this website. where this is also explained.

Community
  • 1
  • 1
watchme
  • 720
  • 1
  • 9
  • 25
  • Can you give me an example please ? – Atul Apr 02 '18 at 13:30
  • In example web site you have mentioned , @Required is essentially used as dependency injection mechanism only . – Atul Apr 02 '18 at 13:46
  • 1
    It is used to check if it is in the XML-configuration file, but not to inject a dependency. The injection is done because the property is mentioned in the XML-file – watchme Apr 02 '18 at 13:58
  • I should probably add that in my answer – watchme Apr 02 '18 at 13:58
  • Agreed. But that means @Required usage outside of XML carries no significance ? What is its significance for Annotations based dependency injection ? How can we related the same logic to non-XML based bean discovery ? – Atul Apr 02 '18 at 14:08
  • @Atul 1. as far as I know, yes! ------ 2. I don't think any ------ 3. Well than you can just normally autowire it. I think it just tells that the injection has to happen through an XML-File. – watchme Apr 02 '18 at 14:24
1

1) You can think of @Required as a check that the property has been eagerly initialised. In other words it requires that it's been injected via configuration (xml or annotation). If annotation is used then you'll see it alongside @Autowired. If the Bean injected does not exist the application fails to startup with a runtime exception.

2) Nothing more nothing less. @Required is very specific in what it's meant to be: a) only applicable on methods, b) requires the bean or else application runtime error on startup. Again, you need dependency injection either via annotation or xml.

3) Most likely you want to know at startup if a Bean is failed to be injected and for that reason you can have @Required along with @Autowired for expressiveness. Functionality-wise you don't need it if you have @Autowired.

Extra notes:

@Autowired has more functionality on the other side of the coin that is - when you want to achieve laziness. So on a setter method:

  1. as you mentioned @Autowired(required = false)
  2. Can also be paired with @Lazy
  3. you can have @Autowired (without required = false) on a setter method whose param is Java 8's Optional achieving the same effect.
dimitrisli
  • 20,895
  • 12
  • 59
  • 63