Difference between #Autowired and #Required with setter injection in Spring - spring

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;
}
}

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

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:
as you mentioned #Autowired(required = false)
Can also be paired with #Lazy
you can have #Autowired (without required = false) on a setter method whose param is Java 8's Optional achieving the same effect.

Related

Spring drawbacks of Lazy annotation

I want to resolve a circular dependency with it.
I am aware that there is a drawback of this annotation namely in case of a bean misconfiguration the error will come to the surface only at invocation time:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Lazy.html
"Please note that such a lazy-resolution proxy will always be
injected; if the target dependency does not exist, you will only be
able to find out through an exception on invocation. As a consequence,
such an injection point results in unintuitive behavior for optional
dependencies."
My question is this really a drawback in any sense if I already use the given bean as non-lazy singleton at other parts of application? Which basically proves that the bean itself can be created.
example:
#Component
class A {
#Autowired
private B b;
}
#Component
class B {
#Autowired
#Lazy
private A a;
}
#Component
class C {
#Autowired
private A a; <- this is the evidence that the bean can be created so it wont fail when injecting it into classB when invoked
}
As long as your configuration is correct, it should work. In some cases, you need circular dependencies and this is the best way that I've found to implement.
Constructor injection is better but won't always work.
Alternatively, you can inject the BeanFactory and fetch in a #PostConstruct or afterPropertiesSet() method, but using #Lazy property injection seems cleaner.

What is the use of RequiredAnnotationBeanPostProcessor in Spring framework?

I am a beginner in Spring framework. I have started learning Spring framework a couple of weeks. I did not get any proper explanation of RequiredAnnotationBeanPostProcessor. Please, someone, help me by giving some example of RequiredAnnotationBeanPostProcessor and where to use this. Thanks in advance.
RequiredAnnotationBeanPostProcessor is a not common used annotation in applications that use Spring.
The #Autowired annotation that provides both the autowiring and the requiring (by default enabled) behaviors is often preferred to.
RequiredAnnotationBeanPostProcessor is a BeanPostProcessor implementation.
The BeanPostProcessor interface defines callback methods that you can implement to provide your own (or override the container’s default) instantiation logic, dependency-resolution logic, and so forth.
In the case of RequiredAnnotationBeanPostProcessor, it enforces required JavaBean properties to have been configured.
Required bean properties are detected through a Java 5 annotation: by default, the Spring's Required annotation.
To be short, it allows to ensure that a bean that declares 'required' properties has actually been configured with values. Note that the value may be null.
For example suppose this model class :
public class Foo {
private Bar bar;
#Required
public void setBar(Bar bar) {
this.bar = bar;
}
}
If setBar() is never invoked during the initialization of the bean, a org.springframework.beans.factory.BeanInitializationException is thrown.
For example this bean configuration will trigger the exception throwing :
#Configuration
public class MyConfig {
#Bean
public Foo getFoo() {
return new Foo();
}
}
Of course if you add #Autowired to setBar() with a resolvable dependency, it will be fine :
public class Foo {
private Bar bar;
#Autowired
#Required
public void setBar(Bar bar) {
this.bar = bar;
}
}
So we could consider that a good use case for RequiredAnnotationBeanPostProcessor is a case where you don't want/cannot specify the autowiring in the class of the bean.
Note also that RequiredAnnotationBeanPostProcessor provides also an additional feature that is according to the javadoc its primary goal :
The motivation for the existence of this BeanPostProcessor is to allow
developers to annotate the setter properties of their own classes with
an arbitrary JDK 1.5 annotation to indicate that the container must
check for the configuration of a dependency injected value.
It means that you may specify another annotation that #Required to indicate the required constraint.
RequiredAnnotationBeanPostProcessor defines indeed a setRequiredAnnotationType() method that you can override to set the annotation to use.
As you can see, the use of RequiredAnnotationBeanPostProcessor is related to very specific corner cases. That's why you probably don't find many examples about it.

Spring Boot Constructor based Dependency Injection

I'm a beginner with Spring Boot and Dependency Injection and I can't get my head around Constructor based Dependency Injection in Spring Boot. I have class called ParameterDate that look like this:
public class ParameterDate {
private Date parameterDateUnadjusted;
private Date parameterDateAdjusted;
private Date parameterDateAdded;
private Date parameterDateChanged;
}
I have another class where I want to use ParameterDate. Normally I would do Field based Injection with
#Autowired
ParameterDate parameterDate;
And where ever needed I just use parameterDate.
How would I do this with Constructor based Injection?
public MyClazzRequiringParameterDate(ParameterDate parameterDate){
this.parameterDate = parameterDate;
}
Since Boot 1.4 #Autowired has been optional on constructors if you have one constructor Spring will try to autowire it. You can just tag the constructor with #Autowired if you want to be explicit about it.
Generally speaking you should favour Constructor > Setter > Field injection. Injecting directly to the field misses the point of DI, it also means your tests are reliant on Spring to inject dependencies into rather than just being able to pass mocks or stubs directly to it. Jurgan Holler has stated that he would remove field injection if at all possible.
#Component
public class ParameterDate {
private Date parameterDate;
#Autowired
public ParameterDate(Date parameterDate){
this.parameterDate = parameterDate;
}
}
Above is an example of constructor injection.
Note that you can use #Autowired annotation also on property's setter method, and since there is no difference between setter method (except of course it's purpose, logic it contains) and any other method, you can use #Autowired on just about any method of the class.
Since autowiring and component scanning go hand in hand, you should mark your class with #Component annotation. This tells Spring that a bean should be created for this class.

What is the magic behind Field #Autowired

I am currently improving my Spring knowledge. I wonder what really happens when I use Spring annotation #Autowire on a field.
Here is a piece of code :
OutputHelper file
#Component
public class OutputHelper {
#Autowired
#Qualifier("csvOutputGenerator")
private IOutputGenerator outputGenerator;
public void setOutputGenerator(IOutputGenerator outputGenerator) {
this.outputGenerator = outputGenerator;
}
// I can focus only on what my code do because my objects are injected
public void generateOutput(){
outputGenerator.generateOutput();
}
}
CsvOutputGenerator file
#Component
public class CsvOutputGenerator implements IOutputGenerator {
public void generateOutput(){
System.out.println("Csv Output Generator");
}
}
Application file
public static void main(String[] args) {
// Create the spring context
ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/spring-module.xml");
// Get the configured OutpuHelper from the spring-module.xml
OutputHelper output = (OutputHelper) context.getBean("outputHelper");
// Display output from the output configured
output.generateOutput();
}
My configuration file just contain <context:component-scan base-package="com.xxx.xxx.output"/>
When I execute this code all work fine. But what makes me surprised is when I delete the setOutputGenerator in OutPutHelper file, my piece of code keeps working. I tought that with this configuration, the OutputHelper was first created with default constructor and initialized with setter.
I expected an error because the variable outputGenerator was not be able to be initialized.
Is anyone can help me to understand ?
The idea to have fields #Autowired is questionable. It works, but it will difficult other aspects of your implementation (i.e. testing).
There are 3 types of injections:
fields - basically configured applying reflection (Field.set(Object, Object)) directly to the field:
#Autowired
private MyInterface field;
setters - with this approach the configuration of each dependency goes through a property (spring goes through all methods and execute each one annotated with #Autowired using Method.invoke(Object, Object...), thus its value is configured using its setter as follows:
#Autowired
public void setField(MyInterface value) {
this.field = value;
}
constructors - the last, and my preferable approach, the constructor injection. That one basically annotates an constructor with #Autowired and instead of using methods or fields, you can configure your bean directly on your constructor. For that spring will elect the a constructor to be used to instantiate your #Component, and it will use an #Autowired if existent or a empty params constructor, invoking it using Constructor.newInstance(Object...). Example:
#Component
public class Implementation {
private MyInterface field;
#Autowired
public Implementation(MyInterface value) {
Assert.notNull(value, "value should not be null");
this.field = value;
}
}
One of the ideas behind Inversion of Control (or Dependence Injection) is to be able to isolate a piece of code in order to provide decent test implementation support.
In order to go deeper, it is necessary to comment that during a unit test you want the class in its isolated form, all you will use with that class are basically mocks for its dependencies (injections).
So, what are the results:
If you do field injection, it will be quite costly to every single time set the beans using some reflection to configure the bean during your tests (another logic needs to be introduced to configure the bean to be tested).
With setter injection approach you will be able to use your own bean to configure it with mocks necessary to isolate your implementation and test its functionality.
And finally, with the constructor injection approach you will have not only the support to configure your bean, but you will be able to require its dependencies. This means that for every new dependency a new parameter on your constructor is added, this brings you come advantages on development time, for example, you will be able to see on development time the unit tests affected with the introduction of that new dependency (once your IDE will point it out for your).
Simple answer
Actually, the setter is useless, since the CDI use java Reflection to access fields.
It means that fields are no longer accessed by method calls.
Reflection allow iterating throught all fields of a class and check if there are annoted with a specific annotation.
In this case, if a field in your class is annoted With #Autowired (or #Inject wich is more J2E complient), the container will iterate throught searching if there is a registered bean that fits the current property.
Going deeper
When you context is starting, the container iterate classes and search all field annoted with #Inject or #Autowired.
For these fields, it search an available bean.
Here is the must simple example :
public class SpringClassInChargeOfDependencyInjection {
public void handdleInjections(T objectWithInjectableField) {
Class<T> clazz = objectWithInjectableField.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Autowired.class) || field.isAnnotationPresent(Inject.class)) {
//find a bean for the type;
Object injectableBean = getAvailablebean(field.getType());
field.setAccessible(true);
//inject the value into the class, this line explain why the setter is not necessary
field.set(objectWithInjectableField, injectableBean);
}
}
}
}
This is a non-working example just to explain how it works.
Tips
You might consider using #Inject instead of #Autowired, the later was created by Spring, #Inject is a part of the the JSR-330. Spring does understand #Inject as well, you just need to add the javax.inject jar dependency to your project. If later you want to switch from spring to something else (guice for example) you won't have to change all your #Autowired annotations
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>

Autowiring doubts in spring?

After going thru autowiring concept
i have got some questions. These are:-
If i need to autowire below class byType or byName , is it mandatory to have setStudent() method in class College?
public class College {
private Student student1;
private String registration1;
}
<bean id="student1" class="Student"/> - in case of byname it will look into id attribute and in case of bytype it will look for class attribute in above
Stetement. Right? If incase it finds two bean dean tags for the same type it will throw fatal error in case of bytype. Correct?
autodetect Scenario chooses constructor or byType through introspection of the bean class. If a default constructor is found, the byType mode
will be applied.
My question here if default constructor is not found and constructor with argument is found then autowire by constructor
will be applied. Correct?
Do we need to specify #Autowired somewhere in College to apply the autowiring. As i can see this in this example
but nothing is specified here
1), 4) There are two separate ways of autowiring in Spring: XML-based and annotaion-based.
XML-based autowiring is activated from XML config, as described here. In the end, it will call setter method, so setStudent() method is required here.
Annonation-based autowiring, on the other hand, is performed via reflection magic. It attempts to fill everything you mark with #Autowired annotation. In fact, it can set private field with no accessors, as in
public class Foo {
#Autowired private Thingy thing; // No getThing or setThing methods
private void doStuff() {
// thing is usable here
}
}
For #Autowired annotaion to work, you will need to define corresponding bean post-processor; it is done by adding the following line to xml config:
<context:annotation-config/>
Note, that these two autowiring methods are independant, and it is possible(but not recommended) to use them simultaneously. In that case, xml autowiring will override annotations.
2) In general, autowiring will fail, if it cannot find one and only one candidate for injection. So, in your case, it will fail with exception upon container creation. There are some fallback quirks, but in general it works reliably.
3) Yes, documentaion says so.
About byName and byType autowiring. While byName autowiring simply tries to match bean name (can be specified with id attribute), byType is a bit more complex than class attribute lookup. It searches beans by type, and it will match interfaces. Example:
public interface SomeService {
void doStuff();
}
public class SomeServiceImpl implements SomeService {
#Override public void doStuff() {
// Implementation
};
}
public class ServiceUser {
#Autowired
private SomeService someService; // SomeServiceImpl instance goes here
}
P.S. You are referencing two different versions of Spring in your question, 2.5 and 3.0. Autowiring behavior is same in both.
In Addition if you are using #Autwired annotation you need to mark the classes as candidates for autowiring. It should be done by using one of these annotations:
#Repository
#Service
#Component
#Controller
and of cause you can configure it in different scopes:
#Scope("prototype")
#Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}
Hope it makes it more clear.

Resources