Spring~Read beans with annotations (property injection, constructor injection, set injection)


It is a very simple way to store and obtain bean objects from spring through annotations. We have already introduced how to bean store them in the spring container. Here we will learn bean how spring to read them from the container through annotations.

Reading bean objects is also called object assembly, object injection, and dependency injection , which is to put the obtained object into a class and let this class use it.

Object injection :
If class A needs to use an instance of class B, you can directly create an instance of class B in class A, or you can take the instance object of class B out of the Spring container and "inject" it into class A like an injection , dynamically managed and used by Spring, this is "injection".

Annotation @Autowired.

Object injection is performed by using annotations @Autowired. This annotation is an annotation of the Spring container configuration. The annotations that belong to the same container configuration are: @Required, @Primary, @Qualifieretc. This annotation is literally understood as autowired, automatic assembly. Assemble the bean object with the class that needs the bean.

The usage is as follows:

property injection

 //属性注入
    @Autowired
    private UserService userService;

Example: We inject an instance of the Service class into the Controller class for use.

Create a UserService class:

package com.Service;

import com.User.User;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    
    

    public User findById(int id){
    
    
        User user=new User();
        if(id==1){
    
    
            user.setName("张三");
            user.setAge(18);
            user.setId(1);
        }else if(id==2){
    
    
            user.setName("李四");
            user.setAge(18);
            user.setId(2);
        }
        return user;
    }
}

Create the UserController class:

package com.Controller;

import com.User.User;
import com.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    
    

    //属性注入
    @Autowired
    private UserService userService;

    public User findById(Integer id){
    
    
        if(id==null){
    
    
            return  new User();
        }
        return userService.findById(id);
    }
}

Create test class:

import com.Controller.UserController;
import com.User.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    
    
    public static void main(String[] args) {
    
    
        ApplicationContext context=new ClassPathXmlApplicationContext("a.xml");
      UserController userController=(UserController) context.getBean("userController",UserController.class);
       User user= userController.findById(2);
        System.out.println(user);
    }
}

output:

User{
    
    name='李四', age=18, Id=2}

Setter injection

public class UserController {
    
    

    //设置一个字段
    private UserService userService;

     //为这个字段生成一个set方法,然后加上注解
    @Autowired  
    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }
  
    //调用bean对象的方法进行使用
    public User findById(Integer id){
    
    
        return userService.findById(id);
    }
}

Constructor injection

public class UserController3 {
    
    
    //先生成一个字段
    private UserService userService;
    
    //然后生成构造方法,前面加上注解
    @Autowired
    public UserController3(UserService userService) {
    
    
        this.userService = userService;
    }
}

Notice:

  • The premise of using annotations to obtain beans is that the class can be scanned by spring, that is, one of several similar annotations such as @Controller, @Component, @Service, etc. needs to be annotated before the class.
  • The first operation of these three injections is to generate a field to be injected into the object . The first is to annotate the field directly. The second is to generate a set method for this field and then annotate it. The third is to generate a field for this field. Construct the method, and then annotate the method. The usage is similar, the function is the same, the first one is easier.
  • When injecting through a constructor, if the current class has only one constructor, the @Autowired annotation can be omitted. If there are multiple constructors, it cannot be omitted.
    insert image description here
    insert image description here

Advantages and disadvantages of the three injections

Property/Field Injection:

  • Advantages : simple and convenient
  • Disadvantages : Can only be used for IOC containers, non-IOC containers will have null pointer exceptions, and the default is non-final, prone to circular dependencies

Constructor injection:

  • Advantages : strong versatility, not restricted by the IOC container, can ensure that the injected class is not empty, and can see which classes the current class needs to work at a glance in the code.
  • Disadvantages : Multiple injections will make the code very cumbersome, and multiple injections do not conform to the idea of ​​a single design. Once constructor injection is used, the default constructor cannot be used.

Set method injection:

  • Pros : Immune to circular dependency problems
  • Disadvantage : Object cannot be made final

Annotate @Resource.

There are two important properties in @Resource: name and type .
Spring resolves the name property to the name of the bean and the type property to the type of the bean.

Object injection can also be achieved through @Resource, similar to @Autowired:

1. Property injection

public class UserController {
    
    
    //添加注解在字段上
    @Resource
    private UserService userService;
    
    public User findUser(Integer id){
    
    
        return userService.findById(id);
    }
}

2. Constructor injection

public class UserController2 {
    
    
   
    private UserService userService;
    
    //先创建字段,然后添加注释在构造方法上
    @Resource
    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }

    public User findUser(Integer id){
    
    
        return userService.findById(id);
    }
}

Notice! !

  • @Resource has no constructor injection
    insert image description here

Difference between @Resource and @Autowired

  • The sources are different , @Autowired comes from the Spring framework, while @Resource comes from the JDK
  • The scope of action is different , @Autowired can perform property injection, setter injection, and constructor injection; while @Resource can only perform property injection and setter injection
  • Different functions , @Resource can be used with more properties, while @Autowired supports fewer properties. For example, @Resource can be used with the name property to complete the alias injection of objects.
  • The injection methods are different . @Autowired is injected according to byType, that is, according to the type of bean, while @Resource is injected according to byName.

Injected object name problem

When we inject an object into a class, @Autowired and @Resource will try to get the object, and the object must be found first.

When looking for this object, it is searched according to two criteria, one is the object name and the other is the object type.
insert image description here

  • First, get it according to the name. If it can't get it, it will get it according to the type. If it can't get it, it will throw an exception.
  • If the names do not match, but the types match, and there are multiple objects with the same type matching, an exception will also be thrown, and it is impossible to determine which one it is.

When searching, we have a variety of solutions:
you can specify a bean through @Resource(name="");
insert image description here
you can also use the @Qualifier qualifier to qualify a bean for search.

   @Resource
    @Qualifier("user1")
    private UserService userService;

Guess you like

Origin blog.csdn.net/Merciful_Lion/article/details/124064384