3.Spring makes it easier to read and store objects

Preface: The core of Spring to make it easier to store and read objects is to use annotations. Next, learn Spring-related annotations to store and read Bean objects.

1. Storing Bean objects

1. Preliminary work: configure scan path (important)

To successfully store objects in Spring, we need to configure the scan package path for storing objects. Only all classes under the configured package with annotations added can be correctly identified and saved to Spring. middle.

Add the following configuration in spring-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
 <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"> <content:component-scan base-package="com.java.demo"></content:component-scan>
</beans>

The part marked in red is particularly important. The class object under the scanning package must be configured, otherwise it cannot be stored in Spring.

2. Add annotations to store Bean objects

If you want to store objects in Spring, there are two annotation types:

1. Class annotation:

@Controller, @Service, @Repository, @Component, @Configuration.

2. ?Method Notes:

@Bean
2.1 @Controller (controller storage)
@Controller//Storing objects into Spring
public class UserController {
   public void say(String name){
       System.out.println("This is " + name);
   }
}

At this time, you need to read the above UserController object first by reading the object, as shown in the following code

public class Application {
    public static void main(String[] args) {
        //1. Get the Spring context
        ApplicationContext context=
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2. Get Bean
        UserController userController=(UserController) context.getBean("userController");
        //3. Call bean method
        userController.say("Controller");
    }
}

operation result:

2.2 @Service (service storage)

The code for using @Service to store beans is as follows:

@Service
public class UserService {
  
    private UserRepository userRepository;
    public void say(String name){
        System.out.println("This is " + name);
    }
  
}
public class App {
    public static void main(String[] args) {
//1. Get the spring context
        ApplicationContext context=
                new ClassPathXmlApplicationContext("spring-config.xml");
     //2. Get the bean
        UserService userService=(UserService)context.getBean("userService");
        
     //3. Call method:
        userService.say("userService");

    }
}

2.3 @Repository (warehouse storage)

Using Repository to store bean code is as follows:

@Repository
public class UserRepository{
    public void say(String name){
        System.out.println("This is " + name);
    }
}

Code to read the bean:

public class App {
    public static void main(String[] args) {
//1. Get the spring context
        ApplicationContext context=
                new ClassPathXmlApplicationContext("spring-config.xml");
     //2. Get the bean
       UserRepository userRepository =(UserRepository)context.getBean("userRepository");
        
     //3. Call method:
        userRepository.say("userRepository");
    }
}
2.4 @Component (component storage)

The code to use ? @Component to store beans looks like this:

The code is almost the same as above. We only need to know the location of the class annotation in the code and how to use it.

2.5 @Configuration (configuration storage)

The code is almost the same as above

3. Why are there so many class annotations?

1. Provide semantic annotations: different annotations better express the function and purpose of beans and improve code readability

2. Implement component-based development: Through different annotations, applications can be developed into components according to business logic functions to achieve flexible application architecture.

3. Implement dependency injection: By using different annotations, dependency injection can be implemented, and Bean dependencies can be automatically injected into the Bean to achieve a more loosely coupled application.

4. Implement AOP functions: By using different annotations, you can implement AOP functions, realize the separation of cross-cutting partners and business logic, and improve the maintainability and scalability of the code.

Although they have the same functions, in order to easily distinguish the functional area to which the code belongs,

For example: @Controller: represents the business logic layer;

@Servie: service layer;

@Repository: persistence layer;

@Configuration: configuration layer

An example is the license plate number in each province. The function of the license plate number is the same, but different license plate numbers make it easier to distinguish where the car belongs.

The relationship between them is as shown in the figure above. Check their source code and find that there is an annotation @Component in these annotations.

Indicate that they themselves belong to “subclasses” of @Component.

2. Bean naming rules

Usually the standard camel case naming is used. When reading, the bean can be obtained by lowercase the first letter, as shown in the figure below.

Wrong approach: If the first character and the first character are both written, the bean cannot be read normally, as shown in the following figure:

According to the naming rules of the bean source code: if the first letter of the bean and the first letter of the bean are both written in letters, the bean cannot be read normally, and the first letter of the bean needs to be stored in capital letters. As shown below

2.1 Method annotation @Bean

Class annotations are added to a class, and method annotations are added to a method, as shown in the following code:

@Component
public class Users {
    @Bean
    public User user1(){
        User user=new User();
        user.setId(1);
        user.setName("Java");
        return user;
    }
}
public class App {
    public static void main(String[] args) {
//1. Get the spring context
        ApplicationContext context=
                new ClassPathXmlApplicationContext("spring-config.xml");
     //2. Get the bean
        User user=(User)context.getBean("U1");
     //3. Call bean method
        System.out.println(user);
    }
}

Note: In the design of the Spring framework, the method annotation @Bean must cooperate with the class annotation to store the object in the Spring container normally, that is, the “@Component” class annotation needs to be added.

2.2 @Bean renaming method:

Method 1: @Bean(“aaa”);

Method 2:@Bean(name=”aaa”);

Method 3:@Bean(value=”aaa”);

Renaming extension: @Bean supports specifying multiple names

@Bean(value={“ccc”,”aaa”);

Note:

1. When @ uses the method name to obtain the Bean object, the method name should be the same as the name of the annotated method, otherwise a NoSuchBeanDefinitionException exception will be thrown.

2. If multiple beans use the same name, no error will be reported later in the program execution, but the objects after the first Bean will not be stored in the container, because the symmetry is only associated with the Bean name when the Bean is created for the first time. If a bean with the same name is stored later, the container will automatically ignore it.

If they return the same object type, the program will report an error. Please see Part 3 for details.

3. Obtain Bean object (object assembly)

Obtaining a bean object is also called object assembly, which means taking the object out and putting it into a certain class, also called object annotation.

Object assembly (object annotation) can be implemented in the following three ways:

1. Attribute note?

2. Structure?Annotation?

3. Setter Note?

3.1 Attribute injection:

Core implementation:

//Injection method 1: Attribute injection
    @Autowired
    private UserService userService;

Property annotation is implemented using @Autowired. Inject the Service class into the Controller class. The code is as follows

The implementation code of the Service class is as follows:

@Service
public class UserService {
    /*
    * Get user data based on ID */
    public User getUser(Integer id) {
        //Pseudocode, no need to connect to the database
        User user = new User();
        user.setId(id);
        user.setName("This is id : " + id);
        return user;
    }
}

The implementation code of the Controller class is as follows:

@Controller
public class UserController {
    //Injection method 1: attribute injection
    @Autowired
    private UserService userService;
    public User getUser(Integer id){
        return userService.getUser(id);
    }
}

Get the getUser method of Controller:

public class UserControllerTest {
    public static void main(String[] args) {
      // 1. Get the Spring context
        ApplicationContext context=
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController=context.getBean(UserController.class);
        System.out.println(userController.getUser(1).toString());
    }
}

Final Results:

3.2 Constructor injection

Constructor injection is to implement injection in the constructor of a class, as shown in the following code:

public class UserController2 {
    //Injection method 2: constructor method injection
    private UserService userService;
    @Autowired
    public UserController2(UserService userService){
        this.userService=userService;
    }
    public User getUser(Integer id){
        return userService.getUser(id);
    }
}

Note: @Autowired can be omitted if there is only one constructor

If there are multiple constructors, you need to add @Autowired to clearly indicate which constructor to use, otherwise an error will be reported.

3.3 Setter injection

Setter injection is similar to the property Setter method implementation. The difference is that the @Autowired annotation needs to be added when setting the set method, as shown in the following code:

public class UserController2 {
    //Injection method 2: constructor method injection
    private UserService userService;
    @Autowired
    public UserController2(UserService userService){
        this.userService=userService;
    }
    public User getUser(Integer id){
        return userService.getUser(id);
    }
}

Precautions:

If the set method in a class does not use the @Autowired annotation,

Then Spring will not automatically inject the bean, and when the set method is called, the parameter value passed in is null.

If you want to use dependency injection to assign values to properties, you should add the @Autowired annotation to the set method or configure it in the XML configuration file.

4. Analysis of the advantages and disadvantages of three types of injection:

Attribute Note:

The advantage is that it is simple, easy to use, and suitable for most scenarios;

The disadvantage is that the integrity of the bean cannot be guaranteed and can only be used in the IoC container. If the IoC container is unavailable, NPE (Null Pointer Exception) will only occur when using it. Final modified variables cannot be injected.

Construction?Law Note?:

This is the annotation recommended by Spring.

Advantages:

1. Generally speaking, it must be ensured that the injected class is not empty before use.

2. You can inject a final modified variable

3. The injected object will not be modified because the constructor will only be loaded once

4. Constructor injection can ensure that the injected object is fully initialized

5. Constructor method injection has better versatility

6. Ensure Bean integrity and perform non-null verification

Disadvantages:

1. The writing method is more complicated than attribute injection.

2. Using constructor method injection cannot solve the problem of circular dependencies.

3. If there are multiple annotations, it will appear bloated, but in this case you should consider whether the current class conforms to the single-responsibility design pattern of the program.

Setter ?Form:

This is the annotation method recommended by earlier versions of Spring, but its versatility is not as good as the constructor method. All current versions of Spring have recommended the method of constructor method annotation for class annotation.

advantage:

1. Usually Setter only sets one property, so Setter injection is more in line with a single design principle

2. Flexibly control Bean attributes and perform non-null verification

shortcoming:

1. The object injected by the setter can be modified. The setter is originally a method, and a method may be called and modified multiple times.

2. It is necessary to define the Setter method in the Bean class, which increases the amount of code.

Summary of the three methods:

In general, property injection is the simplest and most commonly used injection method and is suitable for most scenarios; constructor method injection can ensure the integrity of the Bean and is suitable for scenarios that require forced verification; Setter method injection can flexibly control the Bean’s Properties, suitable for scenarios where Bean properties need to be modified dynamically. In practical applications, the appropriate injection method should be selected based on specific scenarios and needs.

5. @Resource: Another type of note keyword

When performing class injection, in addition to using the @Autowired keyword, you can also use @Resource for injection, as shown in the following code:

@Controller
public class UserController {
    //injection
    @Resource
    private UserService userService;
    public User getUser(Integer id){
        return userService.getUser(id);
    }
}

The difference between @Resource and @Autowired:

1. Different origins: @Autowired comes from Spring, @Resource comes from JDK annotations

2. Support different parameters: Compared with @Autowired, @Resource supports more parameter settings, such as name settings, and obtaining beans based on names.

3. Differences in usage: @Autowired supports constructor injection, while @Resource does not.

4. Idea compatibility support is different: using @Autowired may cause false positives in the idea professional version, but @Resource does not have false positives.

6. Problem with multiple @Beans of the same type reporting errors

When multiple beans below appear and return the same object type, the program will report an error, as shown in the code below:

@Component
public class Users {
    @Bean
    public User user1(){
        User user=new User();
        user.setId(1);
        user.setName("User1");
        return user;
    }
    @Bean
    public User user2(){
        User user=new User();
        user.setId(2);
        user.setName("User2");
        return user;
    }

}
@Controller
public class UserController4 {
    //injection
    @Resource
    private User user;
    public User getUser(){
        return user;
    }
}
public class UserControllerTest {
    public static void main(String[] args) {
      // 1. Get the Spring context
        ApplicationContext context=
                new ClassPathXmlApplicationContext("spring-config.xml");
        UserController4 userController=context.getBean(UserController4.class);
        System.out.println(userController.getUser().toString());
    }
}

result:

The reason for the error is: non-unique Bean object

Processing method:

There are two solutions to solve the problem of multiple beans of the same type:

1. Use ?@Resource(name=”user1″) to define.

@Controller
public class UserController4 {
    //injection
    @Resource(name="user1")
    private User user;
    public User getUser(){
        return user;
    }
}

2. Use @Qualifier annotation to define the name

public class UserController5 {
    //injection
    @Autowired
    @Qualifier(value="user2")
    private User user;
    public User getUser(){
        return user;
    }
}

7. Summary

1. Store objects in Spring:

a. Use class annotations: @Controller, @Service, @Repository, @Configuration, @Component [the relationship between them]

b. Use method annotation: @Bean [Note: Must be used with class annotation]

2. Bean naming rules:

The first and last characters are both written, and the second character is written to get the Bean. If the first and last characters are written,

The characters are all written in ?, so directly use the original Bean name to obtain the Bean.

3. Get objects from Spring:

a. Attribute note?

b. Setter Note?

c. Constructor Note? (recommended)

4. Note? Keywords include:

a. @Autowired

b. @Resource

5. The difference between @Autowired and @Resource:

Different origins; different parameters set when using @Resource. Supports more parameters, such as name.

6. Solve the error of multiple beans of the same type:

a. Use? @Resource(name=””)

b. Use ? @Qualifier(“”)