@Detailed explanation of Autowired usage

Keywords: Java Spring Back-end

@Introduction to Autowired annotation

@Autowired annotation, which can label class member variables, methods and constructors to complete automatic assembly. Use @ Autowired to eliminate set and get methods. Before using @ Autowired, we use this when configuring properties on a bean

<property name="Attribute name" value=" Attribute value"/>   

In this way, the configuration is cumbersome and there are many codes. The @ Autowired annotation is introduced in Spring 2.5.
The following is a specific case
UserRepository.java

package com.proc.bean.repository;

public interface UserRepository {
     
     void save();
}

Here, a UserRepository interface is defined, in which a save method is defined

UserRepositoryImps.java

package com.proc.bean.repository;

import org.springframework.stereotype.Repository;
 
@Repository("userRepository")//Specifies that the identifier name of the bean in IoC is userRepository
public class UserRepositoryImps implements UserRepository{
    @Override
    public void save() {
        System.out.println("UserRepositoryImps save");
    }
}

Define an implementation class of the userrepository interface and implement the save method. Note! It is specified here that the identifier name of the bean in IoC is userrepository

UserService.java

package com.proc.bean.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.proc.bean.repository.UserRepository;
 
@Service
public class UserService {
 
    @Autowired
    private UserRepository userRepository;
    public void save(){
        userRepository.save();
    }
}

Here, you need an attribute instance of UserRepository type. You can find it from the IoC container through @ Autowired automatic assembly and return the instance

applicationContext.xml configuration

<context:component-scan base-package="com.proc.bean" />

Test code:

ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService) ctx.getBean("userService");
userService.save(); //The result is UserRepositoryImps save

@Principle of Autowired

In fact, when spring IoC is started, the container automatically loads an AutowiredAnnotationBeanPostProcessor post processor. When the container scans @ Autowired, @ Resource or @ Inject, it will automatically find the required beans in the IoC container and assemble them to the properties of the object

 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

matters needing attention:
When using @ Autowired, first query the bean of the corresponding type in the container. If the query result is exactly one, assemble the bean to the data specified by @ Autowired. If there are more than one query result, @ Autowired will find it by name. If the result of the query is empty, an exception is thrown. When solving the problem, use required=false
Example: following the above example, we are defining a class to implement the UserRepository interface

package com.proc.bean.repository;

import org.springframework.stereotype.Repository;

@Repository
public class UserJdbcImps implements UserRepository {
    @Override
    public void save() {
        System.out.println("UserJdbcImps save");
    }
}

At this time, after starting the container, there are two instances of userrepository type in the container, one named userrepository and the other userJdbcImps. In UserService

@Autowired
private UserRepository userRepository; //Output result: UserRepositoryImps save

Since two instances of this type are found, the name matching method is used to find the instance named userRepository in the container and automatically assemble it to the parameter. If you want to assemble the instance of userJdbcImps here, in addition to changing the field userRepository name to userJdbcImps, you can also provide a @ Qualifier annotation to specify the name of the bean to be assembled. The code is as follows:

@Autowired
@Qualifier("userJdbcImps")
private UserRepository userRepository; //Output result: UserJdbcImps save

Link above

Note: each class can have many constructor methods, but when @ Autowired is used, only one constructor can be marked as required = true (Note: the default value of required is false).

@Execution order difference between Autowired and construction methods

The following code will report an error:

@Autowired
private Person person;
private Dog dog;

public ServiceImpl(){
	this.dog= person.dog();
}

This error is reported because the Java class will first execute the construction method, and then inject a value into the user annotated with @ Autowired. Initialization order of Java variables:
Static variable or static statement block – > instance variable or initialization statement block – > constructor – > @ Autowired
Therefore, to inject the user value, we can inject it through the construction method

private Person person;
private String dog;

@Autowired
public ServiceImpl(Person person){
	this.person= person;
	this.dog= person.getdog();
}

Using constructor injection, you can specify the loading order of member variables.

Posted by Javizy on Thu, 21 Oct 2021 16:12:21 -0700