A simpler way to use Spring

Some of the most basic methods of storing and reading Bean objects have been described before, but they are not used in Spring at all. So this blog will introduce a simpler method of storing and reading Bean objects. The core of what you want to do is to use annotations. Let's take a look below.

Catalog

?? Store Bean Objects

?? 1. Configure Scan Path

To successfully store the bean object in Spring, you need to configure the scanning package path to store the object here by adding the following to Spring's configuration file, 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">
<!--    Register scanned packages (all stored) bean Under Path)-->
    <content:component-scan base-package="beans"></content:component-scan>
</beans>

What you need to modify here is the path of the base-package. You need to improve the package that you set up to store the bean object. Then Spring will scan from this package. If not, it will not scan!

?? 2. Use five categories of annotations to implement

?? 2.1.@Controller [Controller]

@Controller
public class UserController {
    public void func(){
        System.out.println("Hello, controller");
    }
}

This object is now stored in Spring and then read through the previous fetch

public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //Get the bean,
        UserController controller = context.getBean("userController",UserController.class);
        //Using bean s
        controller.func();
    }
}

Here's a question: What is the id exactly? Obviously, you need to use the camel mode of the class name here! This gives you access to the methods inside the object

?? 2.2.@Service [Service]

@Service
public class UserService {
    public void func(){
        System.out.println("Hello, service");
    }
}

This object is now stored in Spring and then read through the previous fetch

public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //Get Beans
        UserService service= context.getBean("userService",UserService.class);
        //Using bean s
        Service.func();
    }
}

?? 2.3.@Repository [Warehouse]

@Repository
public class UserRepository {
    public void func(){
        System.out.println("Hello, repository");
    }
}

This object is now stored in Spring and then read through the previous fetch

public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //Get Beans
        UserRepository repository = context.getBean("userRepository",UserRepository.class);
        //Using bean s
        repository.func();
    }
}

?? 2.4.@Configuration [Configuration]

@Configuration
public class UserConfig {
    public void func(){
        System.out.println("Hello, config");
    }
}

Configurable must not be used here, but the Configuration annotation, which is the configuration layer

public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //Get Beans
        UserRepository repository = context.getBean("userRepository",UserRepository.class);
        //Using bean s
        repository.func();
    }
}

?? 2.5.@Component [Component]

@Component
public class UserComponent {
    public void func(){
        System.out.println("Hello, component");
    }
}


public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //Get Beans
        UserComponent component = context.getBean("userComponent",UserComponent.class);
        component.func();
    }
}

?? 3. Why do you need five types of notes?

The basic usage of the above five categories of notes is similar, but why use the five types of notes? What is the relationship between them? Let's take a look!

This is the level of division of work of the program, which corresponds to the above annotations. In fact, each annotation corresponds to a different application scenario. The reason why so many annotations are so different is that when the programmer sees the annotation, he can directly understand the purpose of the class. This also improves the readability of the code and allows the programmer to intuitively judge the purpose of the current class.

The relationship between the five major notes:
A simple look at the source code of the five annotations shows that



@Controller, @Service, @Repository, @Configuration are all implemented based on @Component, @Component is the parent of four annotations!

Consider again why bean name is the pattern of a hump.
Look at the source code to find out




You can find that when the first and second characters of the class name are both uppercase, they are returned directly, and when the second character is not uppercase, they are returned in the form of a hump, so it is generally used here in the form of a hump!

?? 4. Use method annotation @Bean to implement

Use method annotations can no longer add annotations to classes, so they can only be added to methods, whereas @Bean cannot be used alone. You need to pair a class annotation to use it (any of the five annotations will work)!

@Component
public class UserBeans {
    //bean annotations are used here. bean annotations can only be placed on Methods
    @Bean 
    public User user1(){
        User user = new User();
        user.setId(1);
        user.setName("Zhang San");
        return user;
    }
}



public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //Get Beans
        //The id here is the method name
        User user = context.getBean("user1",User.class);
        System.out.println(user);
    }
}


This gives you the bean object, where the bean name is not a hump of a class name, but a method name annotated with @Bean!
It would be strange to use the method name directly here, and it doesn't conform to the specifications, so can you modify the bean name? Of course, you can rename Bean objects here by setting the name property!

@Component
public class UserBeans {
    @Bean(name = {"user"}) 
    public User user1(){
        User user = new User();
        user.setId(1);
        user.setName("Zhang San");
        return user;
    }
}

Here's a name to get the object from:

public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //Get Beans
        //The id here is the method name
        User user = context.getBean("user",User.class);
        System.out.println(user);
    }
}


Discovery is okay, so even if the name is modified successfully, you can set more than one name for a bean object here, just put other names in curly braces, while the @Bean naming rules, when the name property is not set, the default name of the bean name is the method name. When the name property is set, the beans can only be obtained by setting the bean name, and then using the method name will be wrong!

?? 2. Get Bean Objects

Getting a bean object, also known as object assembly, means taking the object out and putting it into a class, which is sometimes called object injection. There are three ways to get an object out of a container. Let's see below.

?? 1. Attribute Injection (Field Injection)

Direct use of @Autowired on attributes allows injection

@Repository
public class UserRepository {
    public void func(){
        System.out.println("Hello, repository");
    }
}
@Controller
public class UserController {
    //Property injection, using Autowired
    @Autowired // The precondition is that the UserRepository object is already stored in Spring
    private UserRepository userRepository;
    public void func(){
        userRepository.func();
    }

Now that you've injected the object, let's see if it's successful

public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController controller = context.getBean("userController",UserController.class);
        controller.func();
    }
}


This finding is consistent with the expected results

?? 2. Construction Method Injection

Adding the @Autowired comment to the construction method also implies injection

@Repository
public class UserRepository {
    public void func(){
        System.out.println("Hello, repository");
    }
}
@Controller
public class UserController {
     private UserService userService;
    @Autowired  //Construction method injection, to follow a single principle, multiple parameters will fail
    public UserController(UserService userService){
        this.userService = userService;
    }
    public void func(){
        userService.func();
    }

Now that you've injected the object, let's see if it's successful

public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController controller = context.getBean("userController",UserController.class);
        controller.func();
    }
}


When a construction method passes in more parameters, it cannot be injected correctly and errors will occur, so when using a construction method injection, you need to follow a single principle! You can omit @Autowired when there is only one constructor in a class

?? 3.Setter Injection

@Repository
public class UserRepository {
    public void func(){
        System.out.println("Hello, repository");
    }
}
@Controller
public class UserController {
     private UserService userService;
     @Autowired
     public void setUserService(UserService userService) {
        this.userService = userService;
     }
    public void func(){
        userService.func();
    }

Now that you've injected the object, let's see if it's successful

public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController controller = context.getBean("userController",UserController.class);
        controller.func();
    }
}

What is the difference between the three injection methods?

  • Attribute injection is characterized by very simple writing but poor versatility and can only run in an IoC container. If it is in a non-IoC container, it is very likely that the null pointer will be abnormal.
  • Setter writing was recommended in earlier Spring versions, but Setter injection universality did not pass construction method injection because setter methods may not be available in other languages;
  • After version 3.4, the construction method became the officially recommended version. It is more versatile and ensures that the injection object must be initialized before it is used. The reason why it was not recommended before is that it cannot be injected because of multiple parameters!

?? 4. Another injection keyword @Resource

The injected keyword is not just @Autowired, which is provided by Spring, but JDK also provides an injected keyword @Resource, which is similar to the @Autowired usage, but also has some differences:

  • Origin is different: @Autowired comes from the Spring Framework comment, @Resource is from the JDK comment;
  • Different usage: @Autowired supports property injection, construction method injection, Setter injection, and @Resource does not support construction method injection;
  • The parameters supported are different: @Resource supports more parameter settings, such as name and type settings, while @Autowired only supports required parameter settings;

?? 5.@Bean Injecting a type of parameter multiple times

Problems occur when using @Bean to inject a type of parameter multiple times

@Component
public class UserBeans {
    
    @Bean(name = {"user1"}) 
    public User getUser1(){
        User user = new User();
        user.setId(1);
        user.setName("Zhang San");
        return user;
    }
    @Bean(name = {"user2"}) 
    public User getUser2(){
        User user = new User();
        user.setId(2);
        user.setName("Li Si");
        return user;
    }
}

@Controller
public class UserController {
    @Autowired
    private User user;
    public void func(){
        System.out.println("user:" + user);;
    }
}
public class Main {
    public static void main(String[] args) {
        //Get the context object first
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController controller = context.getBean("userController",UserController.class);
        controller.func();
    }
}

There are two ways to solve this problem: first by name, then by class.

?? 5.1. Precise description of the name of the bean (write the injected name correctly)

You can change the name of the injected bean s to the name value you set yourself.


However, there is a drawback. If this name has already been used, it can no longer be used elsewhere, so other solutions are needed!

?? 5.2. Use the @Resource annotation

I said above that using @Resource can support multiple parameters, and here you can put the name of the bean into the name property, then you can rename the injected bean object name.


But if you don't use the @Resource annotation, of course @Autowired can do the same!

?? 5.3. Use the @Autowired annotation

Using @Autowired without a name attribute does not allow you to set parameters directly like @Resource, which requires that if another comment @Qualifier, which qualifies it to the name of the stored bean object, it can also be resolved


The parameter value in @Qualifier can be omitted because there is only one parameter in @Qualifier, but it is recommended that you write this, do not omit it!

First of all, I would like to introduce myself. Xiaobian graduated from Master Jiaotong University in 13 years, once stayed in a small company, went to factories such as Huawei OPPO, and entered Ali in 18 years until now. Knowing that most junior and intermediate Java engineers often need to grope for growth or sign up for classes to improve their skills, but the tuition fees of nearly 10,000 yuan for training institutions are very stressful. Their own self-study efficiency is low and long, and they are prone to encounter ceiling technology. So I have collected a complete set of learning materials for java development for you. The original intention is very simple. I want to help friends who want to learn by themselves but don't know where to start, and at the same time reduce the burden on you. Add the business card below to get the complete set of learning materials.

Tags: Front-end Android Back-end Interview

Posted by The14thGOD on Thu, 04 Aug 2022 21:30:46 +0300