Article directory
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
, @Qualifier
etc. 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.
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
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.
- 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="");
you can also use the @Qualifier qualifier to qualify a bean for search.
@Resource
@Qualifier("user1")
private UserService userService;