Spring's simpler reading and storage of beans (based on annotations)

Table of contents

① Obtain the dependencies of spring-context and spring-beans from the Maven central warehouse, and introduce the dependencies into pom.xml

② Configure the scanning path 

③Add annotations to store Bean objects (5 types of annotations and method annotations can be used) 

 Class annotations (written on the class, acting on the class)

@Controller: class marked as a controller 

@Service

@Repository

@Component

@Configuration

Why are so many annotations needed? 

The relationship between class annotations (Annotations other than @Component annotations are implemented based on @Component. That is to say, @Component is the parent class of all the above annotations.)

Method annotations (annotations acting on methods) @Bean

Why not just add @Bean annotations, but also need to add class annotations? 

Summarize the usage rules of @Bean annotation: 

④ Get the Bean object from Spring (object assembly/object injection)

Three ways of object injection: 

1. Property injection (@Autowired)

2. Construction method injection (officially recommended writing method)

3. Setter injection 

@Resource annotation and its difference from @Autowired 

1. Different providers 

2. Supported injection methods are different 

3. The supported parameters are different 

The difference between property injection, constructor injection, and Setter injection to obtain beans 


① Obtain the dependencies of spring-context and spring-beans from the Maven central warehouse, and introduce the dependencies into pom.xml

  Configure as follows:

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.24</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.3.24</version>
        </dependency>
    </dependencies>

② Configure the scanning path 

Find the relevant configuration code previously saved in Gitee:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置 Spring 扫描的根路径(此根路径下的所有 Spring 存对象的注解才能生效) -->
    <content:component-scan base-package="com.demo.spring.beans"></content:component-scan>

</beans>

Configure the spring-config.xml file in the resources file and copy the above content (note: the configuration scanning root path needs to be changed to be consistent with your own)

  

③Add annotations to store Bean objects (5 types of annotations and method annotations can be used) 

1: Use five types of annotations: @Controller[控制器], @Service[服务], @Repository[仓库],
@Configuration[配置],Component[组件]

2: By method annotation: @Bean方法

 Class annotations (written on the class, acting on the class)

@Controller: class marked as a controller 

Controller: the class corresponding to the Controller in the three-tier architecture .

The parameter passed in the @Controller annotation is the name of this class object

package com.demo.spring.beans;

import org.springframework.stereotype.Controller;

@Controller("Student")
public class Student {
    public void sayHi(){

        System.out.println("Hi Student");
    }
}

It should be noted that if we pass in parameters in the @Controller annotation, then we must follow the name of the parameter when using it:

 If it is different, the Bean object will not be obtained:

And, if no parameter is passed to @Controller, it is named with a small hump by default (except for the case where the first two letters of the class name are capitalized, such as SUser, then the name is also the default) 

 The above reasons are still due to Spring's source code:

 Find these two methods in the source code:

@Service

The role is the same as that of the Controller, and is used to mark the objects of the "business logic layer".

@Repository

The role is the same as that of the Controller, used to mark the object of the "persistence layer"

@Component

If it does not belong to any of the previous 3 layers, then this annotation can be considered as a "tool".

@Configuration

The role is the same as that of the Controller, used to mark the "configuration class".
The above annotations have the same effect, so I won’t demonstrate them one by one here. 

Why are so many annotations needed? 

This is to make the code more readable, allowing programmers to intuitively judge the purpose of the current class.

General software development is divided into four levels: 

@Controller: represents the business logic layer;
@Servie: service layer;
@Repository: persistence layer;
@Configuration: configuration layer; 

The above @Component is not within these four layers. 

The relationship between class annotations ( Annotations other than @Component annotations are implemented based on @Component. That is to say, @Component is the parent class of all the above annotations .)

Such as @Controller: 

Method annotations (annotations acting on methods) @Bean

 First recreate a User class:

package com.demo.spring.beans;

public class User {
    private int Id;
    private String name;

    public int getId() {
        return Id;
    }

    public void setId(int id) {
        Id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "Id=" + Id +
                ", name='" + name + '\'' +
                '}';
    }
}

Create another UserBeans:

1. Add one of the five major categories of annotations to the class

2. Add Bean annotations to the method

Why not just add @Bean annotations, but also need to add class annotations? 

In order to improve efficiency, when we add five types of annotations, Spring will scan these annotated classes, which can greatly reduce the scope of scanning, and then scan the methods annotated by @Bean.

package com.demo.spring.beans;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;

@Controller
public class UserBeans {
    @Bean//方法返回的对象存储在Spring容器
    public User user(){
        //创建User对象
        User user=new User();
        //设置属性
        user.setId(1);
        user.setName("张三");
        //返回对象
        return user;
    }

}

You can also specify the name of the returned object (the original object name is not available after specifying) 

    @Bean(name = {"userInfo","user2"})
    public User user(){
        //创建User对象
        User user=new User();
        //设置属性
        user.setId(1);
        user.setName("张三");
        //返回对象
        return user;
    }

Get the User object 

import com.demo.spring.beans.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("spring-config.xml");
       User user= context.getBean("userInfo", User.class);
        System.out.println(user.toString());
    }
}

Note: After specifying the name of the returned object, the original object name cannot be used. For example, the above can only use userInfo and user2, but not user:

Summarize the usage rules of @Bean annotation: 

1. When using the @Bean annotation, it should be used together with the five major types of annotations, so that the return value of the method can be injected into the IoC container

2. If the name attribute of the bean is not specified, the default is the method name. Once specified, the method name cannot be used. A bean can specify multiple names

3. When using @Bean to annotate multiple methods, and when they are beans of the same type, be sure to use the getBean() method in the form of ID+class name, otherwise an error will occur

④ Get the Bean object from Spring (object assembly/object injection)

Three ways of object injection: 

1. Attribute injection

2. Construction method injection

3. Setter injection 

1. Property injection (@Autowired)

Attribute injection: use the object that needs to be obtained as an attribute of the class

Inject the Service class into the Controller class as follows:

Service class:

package com.demo.spring.beans;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public void sayHi(){
        System.out.println("Hi UserService");
    }
}

Controller class: 

package com.demo.spring.beans;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    public void sayHi(){
        userService.sayHi();
    }
}

Startup class: 

import com.demo.spring.beans.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
       UserController userController= context.getBean(UserController.class);
       userController.sayHi();
    }
}

2. Construction method injection (officially recommended writing method)

Constructor injection is to implement injection in the constructor of the class:

package com.demo.spring.beans;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController2 {
    private UserService userService;
    //在构造方法上加@Autowired注解
    @Autowired
    public UserController2(UserService userService){
        this.userService=userService;
    }
    public void sayHi(){
        userService.sayHi();
    }
}

App startup class:

import com.demo.spring.beans.UserController2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App3 {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
        UserController2 userController2=context.getBean("userController2", UserController2.class);
        userController2.sayHi();

    }
}

  

Note: If there is only one construction method, the @Autowired annotation above can be omitted. The official setting is like this. If there are more than one, it cannot be omitted, and the @Autowired annotation can only be on one construction method. 

3. Setter injection 

Setter injection is similar to the implementation of the Setter method of the property, except that the @Autowired annotation needs to be added when setting the set method 

package com.demo.spring.beans;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController3 {
    private UserService userService;
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public void sayHi(){
        userService.sayHi();
    }
}

App startup class:

import com.demo.spring.beans.UserController3;
import com.demo.spring.beans.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App4 {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
        UserController3 userController3=context.getBean("userController3",UserController3.class);
        userController3.sayHi();
    }
}

 

@Resource annotation and its difference from @Autowired 

The @Resource annotation is similar to the @Autowired annotation, but they are somewhat different. (Generally still use @Autowired) 

1. Different providers 

@Resource is an annotation provided by jdk, while @Autowired is provided by Spring 

2. Supported injection methods are different 

@Autowired supports the above three injection methods, while @Resource does not support constructor injection

3. The supported parameters are different 

@Resource supports more parameter settings, such as name and type settings, while @Autowired only supports required parameter settings 

The difference between property injection, constructor injection, and Setter injection to obtain beans 

①Property injection is easy to use, but it is limited to use in IoC containers. When using attribute injection at the same time, if the bean corresponding to this attribute is not in the container, the writing method of attribute injection will be invalid.

② Constructor injection, security upgrades, good versatility, and support for non-Ioc containers. It ensures that the property has been injected before using other methods of this class (constructor's sake), avoiding NullPointException.

③Setter method injection, the writing method is a bit more complicated, supports non-IoC containers, and has good versatility, suitable for unit testing. Programmers can pass in different parameters by calling the setter method

Guess you like

Origin blog.csdn.net/m0_67995737/article/details/130301102