spring bean wiring annotation difference @Required @Autowired @Qualifier @Resource

#`@Required`
The `@Required` annotation applies to bean property setter methods and it indicates that the affected bean property must be populated in XML configuration file at configuration time. If you don't have the setting in xml file, the container throws a BeanInitializationException exception. Following is an example to show the use of `@Required` annotation.

```java:Student.java
public class Student {
   private String name;

   @Required
   public void setName(String name) {
      this.name = name;
   }
}
```

```xml:Beans.xml
   <!-- Definition for student bean -->
   <bean id = "student" class = "com.example.Student">
      <!-- the name property must be set otherwise error occurs  -->
      <property name = "name" value = "Zara" />
   </bean>
```

#`@Autowired`
You can use `@Autowired` annotation on setter methods to get rid of the <property> element in XML configuration file. When Spring finds an `@Autowired` annotation used with setter methods, it tries to perform **byType** autowiring on the method. 

```java:Student.java
public class Student {
   private Teacher teacher;
   
   @Autowired
   public void setTeacher(Teacher teacher) {
      this.teacher = teacher;
   }
}
```

```xml:Beans.xml
   <!-- Definition for student bean -->
   <bean id = "student" class = "com.example.Student">
   </bean>
   
   <bean id = "teacher1" class = "com.example.Teacher">
     <property name = "name" value = "A good teacher" />
   </bean>
```
When you still pass values of autowired properties using <property> Spring will automatically assign those properties with the passed values or references. 

```xml:Beans.xml
   <!-- Definition for student bean -->
   <bean id = "student" class = "com.example.Student">
     <property name="teacher" ref="teacher1" />
   </bean>
   
   <bean id = "teacher1" class = "com.example.Teacher">
     <property name="name" value="A good teacher" />
   </bean>
```
By default, the `@Autowired` annotation implies the dependency is required similar to `@Required` annotation, however, you can turn off the default behavior by using `(required=false)` option with `@Autowired`. 

```java:Student.java
public class Student {
   private Teacher teacher;
   
   @Autowired(required=false)
   public void setTeacher(Teacher teacher) {
      this.teacher = teacher;
   }
}
```

#`@Qualifier`
There may be a situation when you create more than one bean of the same type and want to wire only one of them with a property. In such cases, you can use the `@Qualifier` annotation along with `@Autowired` to remove the confusion by specifying which exact bean will be wired. 

```java:Student.java
public class Student {
   private Teacher teacher;
   
   @Autowired
   @Qualifier("student1")
   public void setTeacher(Teacher teacher) {
      this.teacher = teacher;
   }
}
```
```xml:Beans.xml
   <!-- Definition for student bean -->
   <bean id = "student" class = "com.example.Student">
   </bean>
   
   <bean id = "teacher1" class = "com.example.Teacher">
     <property name="name" value="A good teacher" />
   </bean>

   <bean id = "teacher2" class = "com.example.Teacher">
     <property name="name" value="A bad teacher" />
   </bean>
```
#`@Resource`
The `@Resource` annotation takes a 'name' attribute which will be interpreted as the bean name to be injected. You can say, it follows **by-name** autowiring semantics as demonstrated in the following example.

```java:Student.java
public class Student {
   private Teacher teacher;
   
   @Resource(name="teacher1")
   public void setTeacher(Teacher teacher) {
      this.teacher = teacher;
   }
}
```

```xml:Beans.xml
   <!-- Definition for student bean -->
   <bean id = "student" class = "com.example.Student">
   </bean>
   
   <bean id = "teacher1" class = "com.example.Teacher">
     <property name="name" value="A good teacher" />
   </bean>

   <bean id = "teacher2" class = "com.example.Teacher">
     <property name="name" value="A bad teacher" />
   </bean>
```
If no 'name' is specified explicitly, the default name is derived from the field name or setter method. In case of a field, it takes the field name; in case of a setter method, it takes the bean property name.

details ref: 
https://www.baeldung.com/spring-annotations-resource-inject-autowire