2023.11.6 Spring uses annotations to store Bean objects

Table of Contents

Preliminary work

Use class annotations

Five categories of annotations

@Controller

@Service

@Repository (warehouse)

@Component

@Configuration

Use method annotations @Bean

Rename Bean

Additional questions

Relationship between class annotations


Preliminary work

  • Configure the scan path in the configuration file

<?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">
    <!--base-package indicates the path to be scanned-->
    <content:component-scan base-package="com.java.demo"></content:component-scan>
</beans>

Use class annotations

Five categories of annotations

@Controller

  • Belongs to the business logic layer
  • Verify the correctness of the data requested by the user (security system)

@Service

  • Home service layer
  • Detailed execution methods for orchestration and scheduling (Customer Service Center)

@Repository (warehouse)

  • Owned persistence layer
  • Interacting with the database (executor)

@Component

  • Belongs to the public tools category
  • Provide some public methods

@Configuration

  • Belongs to the configuration layer
  • Used to configure some information of the current project (responsible for the global configuration of the project)

Example understanding

  • Create a StudentController class and inject it into the Spring container using the @Controller annotation
  • Replace the @Controller annotation of the instance with @Service, @Repository, @Component, and @Configuration to inject the current class into the Spring container
package com.java.demo;

import org.springframework.stereotype.Controller;

// Use @Controller annotation to store the current class in the spring container
@Controller
public class StudentController {
    public void sayHi() {
        System.out.println("student controller say hi");
    }
}
  • Get the Bean object in the startup class and use the Bean object
import com.java.demo.StudentController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
// Get the Spring context object
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// Get the Bean object
        StudentController studentController = context.getBean("studentController",StudentController.class);
        studentController.sayHi();
    }
}
  • Here we do not use the Bean tag in the configuration file to inject the StudentController object into the Spring container
  • Instead, use the @Controller annotation directly to inject it into the Spring container
  • So when we use the getBean method to obtain the Bean object, its default id is the camel case form of the original class name

Run results:

Note:

  • There are special circumstances in naming the id of the Bean object here
  • Create a SController class
import org.springframework.stereotype.Controller;

@Controller
public class SController {
    public void sayHi() {
        System.out.println("s controller say hi");
    }
}
  • Get the Bean object in the startup class and use the Bean object
import com.java.demo.SController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
// Get the Spring context object
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// Get the Bean object
        SController sController = context.getBean("sController",SController.class);
        sController.sayHi();
    }
}

Run results:

Conclusion 1:

  • By default, the Bean object id is the camel case form of the original class name
  • But if the first letter and the second letter of the class name are both uppercase, then its Bean object id should be the original class name

Five major categories of annotation Bean object id naming rules original code

Conclusion 2:

  • In the configuration file, the tag and the tag can be used at the same time
  • The tag can supplementally inject Bean objects that are not in the scan path

Example understanding

  • Create a UserService class
public class UserService {
    public void sayHi() {
        System.out.println("user service say hi");
    }
}
  • Use the tag to inject the Bean object of the UserService class into the Spring container

  • Get the Bean object in the startup class and use it
import com.java.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
// Get the Spring context object
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// Get the Bean object
        UserService userService = context.getBean("userService",UserService.class);
        userService.sayHi();
    }
}

Run results:

Conclusion 3:

  • Classes that are not in the scan path set in and are identified by the five major annotations will not be injected into the Spring container

Conclusion 4:

  • Classes that are under the scan path set in but are not identified by the five major annotations will not be injected into the Spring container

Conclusion 5:

  • All sub-package classes under the scan path set in will be injected into the Spring container as long as they are annotated with the five major categories

Use method annotation @Bean

  • Compared with the five major categories of annotations added to a certain class
  • Method annotation @Bean, as the name implies, is added to the method

Note:

@Bean annotations must be used together with the five major categories of annotations

  • Only classes with five major annotations will be scanned by Spring
  • Then it will scan whether the methods in the current class are annotated with @Bean
  • This is a strategy dictated by Spring performance design

@Bean annotation Bean object naming rules:

  • By default, the id of the Bean object stored by @Bean is the method name

Example understanding

  • We create an instance class User
//Ordinary user entity class
public class User {
    public Integer uid;
    public String username;
    public String password;
    public Integer age;

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
  • Let’s create another UserBeans class
  • Write a method in this class to create an object of instance class User
  • And use @Bean annotation to inject User’s Bean object into the Spring container
  • Note that the @Component annotation among the five major types of annotations is used here
import com.java.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class UserBeans {
    @Bean
    public User user1() {
        User user = new User();
        user.setUid(1);
        user.setUsername("Zhang San");
        user.setPassword("123456");
        user.setAge(18);
        return user;
    }
}
  • Get the Bean object in the startup class
  • Note that the id when obtaining the Bean object here is user1, which is the method name of the method modified by the @Bean annotation
import com.java.demo.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
// Get the Spring context object
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// Get the Bean object
        User user = context.getBean("user1",User.class);
        System.out.println(user.getUsername());
    }
}

Run results:

Rename Bean

  • By default, the id of the Bean object stored by @Bean is the method name
  • But we can still manually set the id of the Bean object ourselves

Example understanding

  • We can set multiple IDs for the Bean object as shown below

  • Get the Bean object in the startup class
  • At this time, we can obtain the Bean object by selecting an id. The id selected here is u1
import com.java.demo.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
// Get the Spring context object
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// Get the Bean object
        User user = context.getBean("u1",User.class);
        System.out.println(user.getUsername());
    }
}

Run results:

Note:

  • After renaming the Bean object, the default method of using the method name to obtain the object can no longer be used

Supplementary Questions

  • We create a UserBeans class without renaming the Bean object
import com.java.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class UserBeans {
    @Bean
    public User getUser() {
        User user = new User();
        user.setUid(1);
        user.setUsername("Zhang San");
        user.setPassword("123456");
        user.setAge(18);
        return user;
    }
}
  • We create another UserBeans2 class without renaming the Bean object
import com.java.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class UserBeans2 {
    @Bean
    public User getUser() {
        User user = new User();
        user.setUid(2);
        user.setUsername("李思");
        user.setPassword("123456");
        user.setAge(20);
        return user;
    }
}
  • Get the Bean object in the startup class
import com.java.demo.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
// Get the Spring context object
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// Get the Bean object
        User user = context.getBean("getUser",User.class);
        System.out.println(user.getUsername());
    }
}

Run results:

  • We ran the startup class multiple times and found that the Bean object obtained was always the Username of Li Si
  • But Username is Zhang San’s Bean object, and its id is also getUser, but why is it not obtained?
  • Data coverage is involved
  • Because the Username is Zhang San and the Bean object with the id of getUser is first injected into the Spring container
  • At this time, the Bean object whose Username is Li Si and id is getUser is injected into the Spring container
  • Because there is already a Bean object in the Spring containerwith the id of getUser, the Bean object with the Username of Li Si injected later overwrites the Bean object with the Username of Zhang San< /strong>
  • So the Username output of the Bean object obtained by the startup class here is Li Si

We can observe this situation more clearly through the @Oder annotation

  • @Oder annotation is used to control the order of Bean object injection
  • The smaller the parameter value, the greater its weight, and the earlier it will be injected into the Spring container

Relationship between class annotations

Note:

  • @Controller, @Service, @Repository, and @Configuration are all extensions of @Component
  • These annotations can inject the current class into the Spring container, and their functions are basically the same
  • The reasons why there are so many types of annotations are:
  • It allows programmers to know the function of the current class after seeing the annotations

The above class annotations correspond to the JavaEE standard layering (at least three layers)

  1. Control layer
  2. Service layer
  3. Data persistence layer
  • When a class is not suitable to be placed in any of the above three layers, the @Component annotation can be used to extend and supplement it in layers

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java skill treeNotesBasic syntax 139018 people are learning the system

syntaxbug.com © 2021 All Rights Reserved.