Spring - using five types of annotations and Bean annotations to achieve simpler storage

Table of contents

1. Configure the scan path

2. Use annotations to store Bean objects

2.1 @Controller (controller storage)

2.1.1 Can bean tags be used together with component-san?

2.2 @Service (service storage)

2.3 @Repository

2.4 @Component

2.5 @Configuration

2.6 Can the five categories of annotations not be included in the component-scan package?

2.6.1 Even under component-scan, if the five major categories of annotations are not added, the current object cannot be stored in Spring:

2.6.2 Classes under all subpackages under the scan path (component-scan) can also be stored in Spring as long as they are annotated with five categories.

2.6.3 Some people may ask, if the same class name exists in different packages under the scanning path, can it still be stored normally?

2.6 The relationship between the five categories of annotations

2.6.1 Why so many annotations are needed

2.7 Bean naming rules (source code)

2.8 Use method annotations (@Bean) to store Bean objects

2.8.1 Method annotations must be used in conjunction with class annotations

2.8.2 Renaming of @Bean annotations


Preface: When storing beans before, we used to add a line of bean registration content in the Spring configuration file:

But now we only need one annotation to replace the dilemma of writing a whole line of configuration before. Before we start storing, we need to do some preparatory work.

1. Configure the scan path

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

<?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">
<!--只有在com.java.demo包下的spring才去扫描有没有五大类的注解-->
    <content:component-scan base-package="com.java.demo"></content:component-scan>
</beans>

have to be aware of is:

The line marked in red is the package registered for scanning:

2. Use annotations to store Bean objects

To store objects in Spring, there are two types of annotations that can be used:

  • Class annotations: @Controller, @Service, @Repository, @Component, @Configuration.
  • Method annotation: @Bean.

2.1 @Controller (controller storage)

The code to store beans using @Controller looks like this:

package com.java.demo;

import org.springframework.stereotype.Controller;

@Controller //将当前类存储到spring当中
public class StudentController {
    public void sayHi() {
        System.out.println("do student controller sayHi()");
    }
}

Here we first use the method of ApplicationContext to read the object:

import com.java.demo.SController;
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) {
        //1.得到Spring对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        //2.得到bean对象
        StudentController studentController =
                context.getBean("studentController",StudentController.class);
        //3.使用bean对象
        studentController.sayHi();

    }
}

Some people may find it strange that in the getBean() method, the id in the <Bean> tag is filled in before the first parameter passed in, but the bean tag storage is not applicable now, what should be filled in?

Let me talk about the conclusion first: when using class annotations to store beans, there are only two situations:

  • Under normal circumstances, you only need to lowercase the first letter of the class name, which is what the above code shows.
  • Special case: If the original class name and the second letter are capitalized, then the name of the bean is the original class name.

The following is a display of special cases:

The result of running the code:

2.1.1 Can bean tags be used together with component-san?

After verification: the two can exist together.

2.2 @Service (service storage)

The code to store beans using @Service looks like this:

package com.java.demo;

import org.springframework.stereotype.Service;

@Service //将当前类存储到spring当中
public class StudentController2 {
    public void sayHi() {
        System.out.println("do student controller sayHi()");
    }
}

2.3 @Repository

The code to store beans using @Repository looks like this:

package com.java.demo;

import org.springframework.stereotype.Repository;

@Repository //将当前类存储到spring当中
public class StudentController3 {
    public void sayHi() {
        System.out.println("do student controller sayHi()");
    }
}

2.4 @Component

package com.java.demo;

import org.springframework.stereotype.Component;

@Component //将当前类存储到spring当中
public class StudentController4 {
    public void sayHi() {
        System.out.println("do student controller sayHi()");
    }
}

2.5 @Configuration

package com.java.demo;


import org.springframework.context.annotation.Configuration;

@Configuration //将当前类存储到spring当中
public class StudentController5 {
    public void sayHi() {
        System.out.println("do student controller sayHi()");
    }
}

At this time, we use the ApplicationContext method to read the object, and we will find that there is no difference between the five types of annotations.

2.6 Can the five categories of annotations not be included in the component-scan package?

Let’s talk about the conclusion first: No, in order to maintain efficiency, Spring will only scan the annotations under the component-scan package:

2.6.1 Even under component-scan, if the five major categories of annotations are not added, the current object cannot be stored in Spring:

2.6.2 Classes under all subpackages under the scan path (component-scan) can also be stored in Spring as long as they are annotated with five categories.

2.6.3 Some people may ask, if the same class name exists in different packages under the scanning path, can it still be stored normally?

 Under normal circumstances: no, there is a problem when loading the bean:

How to modify it?

  1. Directly modify the class name with the same name
  2. Using the method of @Controller, let the class name have an alias.

Let's take a look at the specific implementation of the second method:

Add an alias to the package SController under demo2:

operation result: 

2.6 The relationship between the five categories of annotations

Observing the source code of @Controller, @Service, @Repository, and @Configuration, it can be considered that they are all "subclasses" of @Component, and they are all extensions for @Component.

2.6.1 Why so many annotations are needed

We have shown you the use of these annotations before, and found that the functions seem to be the same, so why are so many annotations designed?

This is the same as a car's license plate. With today's well-developed traffic network, cars from different provinces may appear at highway intersections in each province, which can help traffic police quickly identify which province the car is from.

The same annotations are the same, which can help programmers quickly identify the purpose of the current class:

  • @Controller: control layer (business logic layer, mainly used to verify the access parameters sent by the front end, customers, etc.)
  • @Service: service layer (service scheduling, equivalent to the customer service center in the airport: used for diversion, etc.)
  • @Repository: data persistence layer (directly operate the database)
  • @Configuration: configuration layer

 The engineering layer of the program:

2.7 Bean naming rules (source code)

Through the example in 2.1, we can see that there are mainly two sets of Bean naming rules:

  • Normally, you only need to lowercase the first letter of the class name.
  • Special case: if the original class name is the first letter and the second letter are capitalized, then the name of the bean is the original class name

Then let's take a look at the naming rules generated by Spring about Bean storage.

We use the keyword search function "beanName" in the idea to see the following:

It uses the decapitalize method in JDK Introspector, the source code is as follows:

2.8 Use method annotations (@Bean) to store Bean objects

It should be noted that the @Bean annotation stores the return value of the method in Spring, so the return value cannot be empty.

Create entity class User:

 operation result:

2.8.1 Method annotations must be used in conjunction with class annotations

Observation draws a conclusion: @Bean annotations must be used in conjunction with class annotations - this is a provision made by Spring to improve performance.

Just imagine, this kind of event that needs to store the return value of the method in Spring is a niche, and it is impossible for Spring to scan methods without class annotations under the scanning path for this small number of methods.

Execute the above code again:

2.8.2 Renaming of @Bean annotations

Why do you need to rename the @Bean annotation?

Here we use the method name to obtain the bean without renaming. This is a bit inappropriate, and it cannot express what is stored in the bean.

Observing the source code of @Bean, we can find that we can use name and value to rename @Bean:

Since name and value have the same effect, here we use name for demonstration:

Annotate @Bean with two names, both of which can be used, whichever one you want.

 After giving it two more names, I used the default method name again and found that the program reported an error.

If there are multiple methods of the same return type in a class, can Spring read it normally?

 The answer is: yes.

The following is a code example:

 If there are the same return value under the @Bean annotation in different classes, will there be an error?

 The answer is no, but there will be cases where new values ​​overwrite old values:

At this time, we can add the @Order annotation to control the order of injection:

The smaller the int value in @Order, the higher the weight value, the earlier the injection:


Guess you like

Origin blog.csdn.net/qq_63218110/article/details/130173980