Spring's five major types of annotations, method annotations, and object injection simplify Bean operations

Table of contents

Why use annotations

Configure scan files:

1. Configure the scan path

1. Five categories of annotations:

 What are the five categories of annotations?

 1.1 @Controller:

1.1.1 Storage Beans

1.1.2 Read Bean

 1.2 @Service:

1.2.1 Storage Beans

1.2.2 Read Bean

 1.3 @Repository:

1.3.1 Storage Beans

1.3.2 Read Bean

 1.4 @Component:

1.4.1 Storage Beans

1.4.2 Read Bean

 1.5 @Configuration:

1.5.1 Storage Beans

1.5.2 Read Bean

 The default id naming rules when five types of annotations match beans

 Why are there so many annotations?

1. The relationship between the five categories of annotations

2. Why use so many annotations?

2. Method annotation @Bean:

 2.1 Storage Bean

 2.2 Get the Bean object

 2.3 @Bean renaming strategy

3. Object assembly (easier to get the Bean object):

 3.1 Property injection:

3.1.1 Analysis of advantages and disadvantages

 3.2 Setter injection:

3.2.1 Analysis of advantages and disadvantages

 3.3 Constructor injection:

3.3.1 Analysis of Advantages and Disadvantages

4. @Resource annotation:

 4.1 The difference between @Resource and @AutoWired:

4.1.1 Solve the same type of @Bean error reporting



Why use annotations

        Using these five class annotations simplifies the storage and retrieval of beans. In fact, it is not limited to the five major types of annotations. Other annotations and injection methods use the same principle to simplify operations. Beans can be stored directly in the Spring container.

        In the previous article, every time we store a new bean, we need to add a new line of <bean><bean> tags in the configuration file spring-config.xml, which is obviously troublesome, so in this article we mainly introduce One-and-done method: configure the scan file-path;

Configure scan files:

        Configuring scan files is a must;

1. Configure the scan path:

        First build the Spring project, and then understand the following:

        ① Create a configuration file in the resources package, named: spring-config.xml;

        ② Add Spring configuration content 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">
    <content:component-scan base-package="com.java.demo"></content:component-scan>
</beans>

        It should be noted that the <content:component-scan><content:component-scan> tag, the most important inside of it is the path of base-package, the meaning of this path is shown in the figure below:

        From another perspective: For a class or object that is not under the final path, even if it is annotated, it cannot be stored as a Bean in the Spring container;

---------------------------------------------- Pre-work completed --------------------------------------------------


1. Five categories of annotations:

What are the five categories of annotations?

@Controller (controller storage): can verify the correctness of the data requested by the user;

@Service (service storage): Serves the execution of specific methods for orchestration and scheduling;

@Repository (warehouse storage): interact with the database;

@Component (component storage): manage components, tool classes, etc.;

@Configuration (configuration storage): manage configuration items, settings, etc.;

1.1 @Controller:

        In order to adapt to the javaEE standard layering, create a response-level package before demonstrating the code, and create classes in the package (the same is true later, and the standard layering is described below);

1.1.1 Storage Bean:

        Like this, write a PersonController class and add the class annotation @Controller to scan the bean through the configuration path and put it in the Spring container;

@Controller
public class PersonController {
    public void myHobby() {
        System.out.println("psController -> 我爱敲代码");
    }
}

1.1.2 Read Bean:

        Create a startup class under the initial java package: App class, get Spring object, Bean object;

        The result of the operation shows that we did not add a line of manual injection such as <bean id="" class=""></bean> in the configuration file like the original one, and we can successfully read the Bean object - personController, which is The benefits of @Controller annotation automatic injection;

// 启动类
public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        PersonController personController =
                context.getBean("personController",PersonController.class);
        personController.myHobby();
    }
}

------------------------------------------------------------------------------------------------------

1.2 @Service:

1.2.1 Storage Bean:

@Service
public class PersonService {
    public void myHobby() {
        System.out.println("psService -> 我爱敲代码");
    }
}

1.2.2 Read Bean:

public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        PersonService personService = context.getBean("personService",PersonService.class);
        personService.myHobby();
    }
}

------------------------------------------------------------------------------------------------------

1.3 @Repository:

1.3.1 Storage Bean:

         Create a package called repository and create the class PersonRepository under the package:

@Repository
public class PersonRepository {
    public void myHobby() {
        System.out.println("psRepository -> 我爱敲代码");
    }
}

1.3.2 Read Bean:

public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        PersonRepository personRepository =
                context.getBean("personRepository",PersonRepository.class);
        personRepository.myHobby();
    }
}

1.4 @Component:

1.4.1 Storage Bean:

        Create a package named Component and create a class PersonComponent under the package:

@Component
public class PersonComponent {
    public void myHobby() {
        System.out.println("psComponent -> 我爱敲代码");
    }
}

1.4.2 Read Bean:

public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        PersonComponent personComponent =
                (PersonComponent) context.getBean("personComponent", PersonComponent.class);
        personComponent.myHobby();
    }
}

1.5 @Configuration:

1.5.1 Storage Bean:

        Create a package called configuration and create the class PersonConfiguration under the package:

@Configuration
public class PersonConfiguration {
    public void myHobby() {
        System.out.println("psConfiguration -> 我爱敲代码");
    }
}

1.5.2 Read Bean:

public class App {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        PersonConfiguration personConfiguration =
                context.getBean("personConfiguration",PersonConfiguration.class);
        personConfiguration.myHobby();
    }
}


The default id naming rules for five types of annotations matching Bean:

        The above directly stores the Bean in the Spring container through annotations. We have not manually set its id, so how to write the id when reading?

        id has default rules: double-click shift, find the AnnotationBeanNameGenerator method, alt + 7 to directly view the buildDefaultBeanName method:

 Then enter its internal decapitalize() method:

 The conclusion can be drawn through the source code: under the @Controller annotation, it is stipulated by default:

  1. The first letter of the class is capitalized, and the second letter is lowercase, then the id is the class name with the first letter lowercase;
  2. The first letter of the class is capitalized, and the second letter is also capitalized, then id is the original class name;

Illustration: 


Why are there so many annotations?

1. The relationship between the five categories of annotations:

        You can also see through the source code of the five annotations: @Controller, @Service, @Repository, @Configuration The implementation of these four annotations all depends on the @Component annotation, so it can be understood that the first four annotations are the "children" of the @Component annotation class", which is an extension of it .

2. Why use so many annotations?

        This has to mention the javaEE standard layering. Since the Spring framework is aimed at enterprise development, these annotations are also designed to adapt to the development rules and business logic to a certain extent.

        JavaEE standard layering is a logical hierarchical structure model designed by major companies for efficient development, mainly divided into: presentation layer—> control layer—> service layer—> data persistence layer;

        Writing code is not only for program design, but also for programmers to see. Although the functions of the five annotations are the same, they each represent a design layer. In the development process, which classes are used where On the first level, with the help of corresponding annotations, the identification function can be intuitively performed, which is convenient for process scheduling.


2. Method annotation @Bean:

        In addition to the five types of annotations introduced above, there is also a "method annotation" specially used on methods: @Bean;

        The role of the @Bean annotation: tell the method to generate a Bean object, and hand this object over to the Spring IoC container for management, so this method returns the created object;

2.1 Storage Bean:

        First create a bean package under the demo package, and create a class PersonBean under the package:

2.2 Get the Bean object:

        Objects stored through the @Bean annotation cannot be obtained as before, because the id naming rules of this annotation are different from those of the five major annotations;

As shown in the picture:

Notice! There are two reasons for the above error:

  1. @Bean naming rules, by default, the stored Bean object name and method name are consistent;
  2. @Bean annotations must be used in combination with five types of annotations; this is required to ensure Spring performance;

Modify the above code:

2.3 @Bean renaming strategy:

        By default, the id of the object stored in the @Bean annotation is the same as the method name. In addition, it can also be renamed according to the needs of the programmer;

        Writing:

  •         Add brackets () after @Bean, use { } for brackets, and multiple id names can be set inside;
  •         The attributes inside { } can be name or value, as shown in the following figure; 

After modification: 

 You can also omit and write:

  • After renaming in this way, the generated name or value is used as an array to store multiple names of the Bean;
  • After using renaming, the default method name acquisition is no longer feasible;


3. Object assembly (easier to get the Bean object):

        Reading the Bean object from the container is also called "object assembly" , which is to take the object out and put it into a certain class, sometimes called "object injection" ;

The three new injection methods described below:

  1. attribute injection;
  2. Setter injection;
  3. constructor injection;

3.1 Property injection:

        Attribute injection needs to be annotated with @Autowired;

        Example: Now there is a data table personDao, which stores the instance of the PersonBean created above, so the idea is: create a PersonDao entity class, and directly inject the Bean object of the PersonBean class into the PersonDao class by means of property injection in this class ;

3.1.1 Analysis of advantages and disadvantages:

advantage:

  1. Easy to write and easy to use;

shortcoming:

  1. Objects modified by final cannot be injected;

  2. Applies only to IoC containers;
  3. NPE (Null Pointer Exception) occurs only when used;
  4. It is easy to violate the single design principle;

3.2 Setter injection:

        Setter injection also uses the @Autowired annotation, but it does use the setter() method;

        Example: Still inject the PersonBean object into the PersonDao class, modify the code slightly, and add the annotation to the Setter() method this time;

3.2.1 Analysis of advantages and disadvantages:

advantage:

  1. Since the Setter() method only passes one object at a time, it conforms to the single design principle, and it is the injection method officially recommended by Spring in the early stage;
  2. Ensure that the object injected into the class before use is not empty;

shortcoming:

  1. Objects modified by final cannot be injected;
  2. The injected object may be modified by other methods inside the class;

3.3 Constructor injection:

        The injection of the construction method still needs to use the @Autowired annotation, but here it is used on the construction method;

        Precautions:

  • If there is only one constructor, the @Autowired annotation can be omitted;
  • If there are multiple constructors, you must use the @Autowired annotation to indicate which constructor to use;

        Example: still inject the PersonBean object into the PersonDao class, modify the code slightly, and add the annotation to the constructor this time;

3.3.1 Analysis of advantages and disadvantages:

advantage:

  1. You can inject final modified objects, because the final modified objects in java are either directly assigned or assigned in the constructor, so they are available;
  2. The injected object will not be changed;
  3. Ensure that the injected object is correctly initialized and not empty;
  4. Good versatility;
  5. Spring's official injection method is currently the most recommended;


4. @Resource annotation:

        This annotation is also used for object injection, see the demo first:

4.1 The difference between @Resource and @AutoWired:

  • Different sources: @Autowired comes from Spring, @Resource comes from JDK itself;
  • Functional differences: @Resource supports more parameter settings than @Autowired;
  • Scope difference: @Resource cannot be used for constructor injection, while @Autowired can be used for the above three injection methods;
  • Different search methods: If multiple copies of the same type of Bean are stored, the two search methods are different. @Resource first checks by name, and then checks by type; while @Autowired first checks by type, Then check according to the name; so @Resource is more suitable for finding multiple beans of the same type;

4.1.1 Solve the same type of @Bean error reporting problem:

        When multiple copies of the same type of Bean are stored, if you only use Spring's @Autowired annotation to inject into the class, there may be an error that no unique matching target can be found.

        Example: Two puppies with different colors are stored in the DogsBean class using the @Bean annotation, and now I want to inject a specified puppy in the DogController class;        

 An error occurs when running: cannot match a unique value.

Solution:

Method 1: Use @Resource(name= ""): Because the parameters of the @Autowired annotation can only be values ​​of type Boolean, you cannot specify a name, but @Resource can;

 Method 2: Use the @Qualifier(value="") annotation: Some people may just want to use the @Autowired annotation, that’s fine, then use it in conjunction with the @Qualifieer annotation;

 

 

       

Guess you like

Origin blog.csdn.net/m0_65190367/article/details/130694052