Spring uses annotations to access objects more easily

Spring uses annotations to access objects more easily

​ The previous article was the most original creation and use. This article mainly talks about the core of Spring's simpler storage and reading of objects.annotation, is also the method "comment" most used by enterprises in daily life, so the content of this article is very important! ! !

1. Simpler storage of Bean objects

1.1 Preliminary work

​ Need to set the root path of the component Component in the Spring 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">
    <!-- 配置一下:bean注解扫描的根路径(方面后面更简单存储对象到spring容器)-->
    <content:component-scan base-package="根路径"></content:component-scan>
</beans>

This is a very important step. Create an xml file under the resources package to configure Spring information. This mainly adds a component scanning path code.

<content:component-scan base-package="组件扫描根路径"></content:component-scan>

❓❓❓The question is coming, why do you need to set this, can't you add bean objects before?

​ The function of using the root path of the scanning package: this configuration information can scan the classes below the root path you set, scan whether annotations are added, store the annotated classes in the spring container, and scan all files without adding the root path range If it increases the workload, the efficiency is not high and the performance is affected.

Note that annotations will be added to spring only if annotations are added to the root path. Even if annotations are added to the root path, they will not be added to spring

​ Advantages of using the scan package path:

  • There is no need to add bean objects in the configuration file every time the registration content is used. When doing projects later, each registration of bean objects will increase the workload and the accuracy is not high. It is more convenient and faster to scan package configuration and add annotations directly into spring to improve efficiency and improve performance
  • The configuration file information code is less, not complicated, just focus on the root path
  • Used in conjunction with annotations, currently companies mainly use annotations instead of the original method

insert image description here

2. Add annotations to store in Spring (save)

2.1, class annotation

2.1.1、@Controller

import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    
    
    public void sayHi() {
    
    
        System.out.println("hi UserController");
    }
}

The @Controller annotation is equivalent to storing bean objects in the spring container:

<bean id="userController" class="com.yuanye.beans.userController"></bean>

The @Controller annotation stores the current object in the container when spring starts. The method of obtaining objects is still the old three steps:

1. Get the Spring context

2. Use the context object to obtain a bean

3. Use beans

The specific operation steps can be seen in this article Spring core and create and use

2.1.2、@Service

Store objects in spring container

import org.springframework.stereotype.Service;

@Service
public class UserService {
    
    
    public void sayhi() {
    
    
        System.out.println("hi UserService");
    }
}

The @Service annotation is equivalent to storing the bean object in the spring container:

<bean id="UserService" class="com.yuanye.beans.UserService"></bean>

2.1.3、@Repository

Store objects in spring container

import org.springframework.stereotype.Repository;

@Repository
public class UserRepository {
    
    
    public void sayhi() {
    
    
        System.out.println("hi UserRepository");
    }
}

It is the same as the method above, and will not be repeated here.

2.1.4、@Component

that's all.

import org.springframework.stereotype.Component;

@Component
public class UserComponent {
    
    
    public void sayHi() {
    
    
        System.out.println("hi,UserComponent");
    }
}

2.1.5、@Configuration

Ditto.

import org.springframework.context.annotation.Configuration;


@Configuration
public class UserConfiguration {
    
    
    public void sayHi() {
    
    
        System.out.println("hi,UserConfiguration");
    }
}

2.2, the difference between class annotations

❓❓❓Question: Although their functions are the same, what is the difference between them? ?

​ It is mainly used to deal with business logic, so that programmers can understand the use of a certain type in business functions at a glance when using a certain annotation.

  • @Controller: Represents the business logic layer (first interacts with the front-end to verify)
  • @Service: Indicates the service layer
  • @Repository: persistence layer
  • @Configuration: configuration layer
  • @Component: entity class

The engineering layer diagram of the program is as follows:

image-20230709000704200

This figure also details the role of each annotation.

2.2.1, the relationship between class annotations

​ From the source code, annotations such as @Controller / @Service / @Repository / @Configuration all have @Component annotations.

image-20230709001740243

Conclusion: annotations such as @Controller / @Service / @Repository / @Configuration themselves belong to @ComponentSubclass

2.3. Method Notes

Method annotations are annotations placed on methods

2.3.1、@Bean

Goal: @Bean stores the object returned by the current method in the Spring container

Code:

import com.yuanye.model.UserInfo;
import org.springframework.context.annotation.Bean;

public class UserBeans {
    
    
    @Bean
    public UserInfo getUser() {
    
     // 方法名就是 bean name
        UserInfo userInfo = new UserInfo();// 伪代码
        userInfo.setId(1);
        userInfo.setName("鸢也");
        userInfo.setPassword("123456");
        return userInfo;
    }
}

This is a registration method in Spring, and there are still three steps to get this method, except that the bean name is the name of the method

UserInfo userInfo = applicationContext.getBean("getUser",UserInfo.class);

But writing the program like this will report an error:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException:

❓❓❓Why is this again? ?

2.3.1.1. Method annotations should be used together with five types of annotations

The answer is that method annotations should be used in conjunction with class annotations. This is how spring was designed from the beginning.

❓❓❓Why is it designed like this? ? ?

The reason is due to performance considerations: it is equivalent to adding a scope. Without adding a scope, a project may have thousands of methods. If you have to scan it to check whether to store the return value in Spring, then the cost is too high , low efficiency and high cost. Therefore, method annotations should be combined with class annotations to implement object hosting.

Correct code:

import com.yuanye.model.UserInfo;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class UserBeans {
    
    
    @Bean
    public UserInfo getUser() {
    
     // 方法名就是 bean name
        UserInfo userInfo = new UserInfo();
        userInfo.setId(1);
        userInfo.setName("鸢也");
        userInfo.setPassword("123456");
        return userInfo;
    }
}
2.3.1.2, @Bean heavy naming

​ @Bean has a property that it can rename the id name.

  • Multiple names can be assigned to the current object
  • The object obtained using the multi-given name is the same
  • After renaming, the original method name can no longer be used as the id name (the original method id name will not get the object)
import com.yuanye.model.UserInfo;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class UserBeans {
    
    
    @Bean(name = {
    
    "user","userfo"}) //@Bean("user")
    public UserInfo getUser() {
    
     // getUser 已经无法再使用,得不到对象
        UserInfo userInfo = new UserInfo();
        userInfo.setId(1);
        userInfo.setName("鸢也");
        userInfo.setPassword("123456");
        return userInfo;
    }
}

​ When he renames, the bean id is obtained by renaming, which is more convenient to operate. The above two ways of writing are both possible, if it is a renaming parameter format @Bean("user"), multiple renaming parameter formats@Bean(name = {"user","userfo"})

Note: If you use renaming, you can only use the old method after renaming to get the object name. You cannot use the original method name again, because the program will report an error and you will not be able to get the current object.

3. Bean (object) naming

​ First look at the source code: (the naming method generally used in classes) is usually used on the bean id (name)

public static String decapitalize(String name) {
    
    
        if (name == null || name.length() == 0) {
    
    
            return name;
        }
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                        Character.isUpperCase(name.charAt(0))){
    
    
            return name;
        }
        char chars[] = name.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }

​ In the second if judgment statement, it can be seen that if the first character and the second character of a certain class are capitalized, then the original name will be returned without modification;

​ In line 10 of the code, if the first character is uppercase and the second character is lowercase, then the name of the bean needs to be modified by changing the first letter to lowercase.

Fourth, get the Bean object (object assembly)

@Autowired

​ Obtaining a bean object is also called object assembly . It is to take the object out and put it in a certain class. Sometimes it is also called object injection (DI: Dependency Injection).

There are 3 ways of object injection:

  • Attribute injection (commonly used by enterprises and individuals)
  • Constructor injection (official recommendation)
  • Setter injection

How to understand injection?

​ During the running of the program, the dependent classes required by the current class are dynamically added. For example, if class A needs to call the method of B, then class A needs to depend on class B and needs B objects. Then the process of dynamically loading class B in class A is called "injection".

To put it bluntly, it is to take the object into the current object in Spring

​ The trilogy of the old method we used before:

1. Get the Spring context

2. Use the context object to obtain a bean

3. Use beans

Now it can also be done with one annotation.

4.1. Attribute injection (commonly used by enterprises and individuals)

​Using property injection to get the object, the annotation of the obtained object is @Autowired, and then we use @Service to inject into the method of @Controller

The @Controller code is implemented as follows:

@Controller
public class ArtController {
    
    
    @Autowired
    private ArtService artService;

    public void addArt(String title, String content) {
    
    
        if (title!=null && content!=null &&
                !title.equals("") && !content.equals("")) {
    
    
            // 满足校验条件就 执行 Service
            artService.addArt(title,content);//注入了ArtService类就可以使用里面的方法了
        }else {
    
    
            System.out.println("添加文章失败,前端传递了非法参数");
        }
    }
}

The @Serviced code is as follows:

@Service
public class ArtService {
    
    
    public void addArt(String title,String content) {
    
    
        System.out.println("执行了文章的 Service 方法:" +
                ""+title+" | "+content);
    }
}
@Autowired
private ArtService artService;

This code is the code of attribute injection, which dynamically injects the ArtService object into the ArtController class.

Operation sequence: first use the type to query, if the object of the same type is queried in Spring, it will be returned directly; otherwise, use the class name to query, if neither of them can be queried, then the injection fails, otherwise it is successful. Attribute injection means that the class and class name in the attribute you apply for can be found in spring, and if the class cannot be found, replace it with the class name.

4.2. Construction method injection (official recommendation)

​ When only one constructor is used in a class, annotate @Autowired at this timecan be omitted, @Autowired cannot be omitted when there are multiple constructors. When there are multiple construction methods, if you need to inject that class, add the annotation @Autowired to the construction method

image-20230710203446560

​ This is the officially recommended method. It is versatile and has good portability. The disadvantage is that multiple injection codes will appear bloated. Of course, you can also change the design pattern so that the code will not be too bloated.

4.3. Setter injection

​ The annotations in the setter injection must not be omitted, no matter whether it is one or more setter methods, this must be clearly distinguished from the constructor injection.

private ArtService artService;
@Autowired
public void setArtService(ArtService artService) {
    
    
    this.artService = artService;
}

​ Here is mainly to create a setter method to inject, which is almost the same as the construction method, but the annotation needs to be paid attention to.


4.4 Comparison of the differences between the three injections (interview)

1. Attribute injection: the advantage is that the method is the simplest and the code is the least; the disadvantage: this method is only applicable to IoC containers, and non-IoC containers cannot be recognized. (But businesses and individuals often use this method)

2. Construction method injection: it is the officially recommended solution. Advantages: better versatility, high code portability; Disadvantages: more code, looks bloated. (official recommendation)

3. Setter injection: It is the injection method recommended by the early version of Spring, which has good versatility. Now it is recommended to use the constructor injection and also the default injection method. (recommended for earlier versions)


@Resource another way of injection

​ The function of @Resource is consistent with that of @Autowired, but there are also differences.

insert image description here

according to the picture above

  • The first difference is that the set parameters are different. You can only set one attribute with @Autowired, but you can set multiple parameters with @Resource.
  • Their births are different: @Autowired comes from the Spring framework, @Resource comes from the JDK.
  • The modified objects are different: @Autowired can be used for property injection, constructor injection, Setter injection,@Resource can only be used for property injection and Setter injection, not for constructor injection.

For the situation of multiple parameters, Spring also thought of a way to solve it.

For an object type to be injected by Spring multiple times, we can use the @Autowired + @Qualifier.

Format:

1、@Resource(name = “”)

@Resource(name = "user1")
private UserInfo userInfo;

2、@Autowired + @Qualifier

@Autowired
@Qualifier("user1")//@Qualifier(value = "user1")
private UserInfo userInfo;

Summarize:

1. Store objects in Spring:

  • Use class annotations @Controller / @Service / @Repository / @Configuration /@Component [note the relationship between their annotations]
  • Use method annotation @Bean [must be used with 5 major annotation classes]

2. Get the object from Spring:

  • attribute injection
  • constructor injection
  • Setter injection

4. Injected keywords:

  • @Autowired
  • @Resource

The difference between the two keywords: birth is different; parameter settings are different, @Autowired supports one attribute parameter, @Resource supports multiple parameter settings

5. Solve the method of injecting multiple beans into one object type by Spring

  • Use @Resource(name = "")
  • Use @Autowired + @Qualifier("")

Guess you like

Origin blog.csdn.net/qq_54219272/article/details/131648825
Recommended