Learn spring 5 architecture from scratch -- Bean scope and automatic assembly technology

Scope of Bean

In Spring, the main bodies that make up the application and the objects managed by the Spring IOC container are called bean s.
Simply put, a bean is an object initialized, assembled, and managed by the IOC container

Among the several scopes, the request and session scopes are only used in web-based applications (don't care what web application framework you use), and can only be used in Web-based Spring ApplicationContext environment

Singleton

When the scope of a bean is Singleton, there will only be one shared bean instance in the Spring IoC container, and all requests for a bean will only return the same instance of the bean as long as the id matches the bean definition.
Singleton is a singleton type, which automatically creates a bean object when creating a container. It exists whether you use it or not, and the object obtained each time is the same object. Note that the singleton scope is the default scope in Spring.
To define a bean as a singleton in XML, you can configure it as follows:

<bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">

Test:

@Test
public void test03(){
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    User user = (User) context.getBean("user");
    User user2 = (User) context.getBean("user");
    System.out.println(user==user2);
}

Prototype

When the scope of a bean is Prototype, it means that a bean definition corresponds to multiple object instances. A Prototype scoped bean will cause a new bean instance to be created each time a request is made to the bean (inject it into another bean, or call the container's getBean() method programmatically).
Prototype is a prototype type. It is not instantiated when we create a container. Instead, we create an object when we obtain a bean, and the object we obtain each time is not the same object. As a rule of thumb, you should use the prototype scope for stateful beans and the singleton scope for stateless beans.
Define a bean as a prototype in XML, which can be configured as follows:

<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>  
 perhaps
<bean id="account" class="com.foo.DefaultAccount" singleton="false"/>

Request

When the scope of a bean is Request, it means that in an HTTP Request, a bean definition corresponds to an instance; That is, each HTTP Request will have its own bean instance, which is created according to a bean definition.
This scope is only valid in the case of web-based Spring ApplicationContext. Consider the following bean definitions:

<bean id="loginAction" class="cn.csdn.LoginAction" scope="request"/>

For each HTTP request, the Spring container will create a new loginaction bean instance according to the loginaction bean definition, and the loginaction bean instance is only valid in the current HTTP request. Therefore, you can safely change the internal state of the created instance according to the needs, while the instances created according to the loginaction bean definition in other requests, You will not see these state changes specific to a request. When the processing of the request ends, the bean instance of the request scope will be destroyed.

Session

When the scope of a bean is Session, it means that in an HTTP Session, a bean definition corresponds to an instance. This scope is only valid in the case of web-based Spring ApplicationContext. Consider the following bean definitions:

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>

For an HTTP Session, the Spring container will create a new userPreferences bean instance according to the userPreferences bean definition, and the userPreferences bean is only valid in the current HTTP Session. Like the request scope, you can safely change the internal state of the created instance as needed. For instances created according to userPreferences in other HTTP sessions, you will not see these state changes specific to an HTTP Session. When the HTTP Session is finally discarded, the beans within the scope of the HTTP Session will also be discarded.

Automatic assembly of Bean

  • Automatic assembly is a way to use spring to meet bean dependencies
  • spring will find the bean that a bean depends on in the application context

There are three assembly mechanisms for bean s in Spring:

  • Explicit configuration in xml;
  • Explicit configuration in java;
  • Implicit bean discovery mechanism and automatic assembly.

Here we mainly talk about the third kind: automated assembly bean.

Spring's automatic assembly needs to be implemented from two perspectives, or two operations:

  • Component scanning: spring will automatically discover the bean s created in the application context;
  • Autowiring: spring automatically satisfies the dependencies between bean s, which is what we call IoC/DI;
    The combination of component scanning and automatic assembly exerts great power to minimize the configuration of display.

It is recommended to use annotations instead of auto assembly xml configuration

Build environment test

Create two new entity classes, Cat Dog, with a method named shot

public class Cat {
    public void shout() {
        System.out.println("miao~");
    }
}
public class Dog {
    public void shout() {
        System.out.println("wang~");
    }
}

Create a new User class

package com.pag.pojo;

public class User {
    private Cat cat;
    private Dog dog;
    private String str;

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }
}

Write 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dog" class="com.pag.pojo.Dog"/>
    <bean id="cat" class="com.pag.pojo.Cat"/>
    <bean id="user" class="com.pag.pojo.User">
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
        <property name="str" value="pag"/>
    </bean>
</beans>

Test class:

    @Test
    public void test1() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) context.getBean("user");
        user.getCat().shout();
        user.getDog().shout();
    }

byName

autowire byName
In the process of manually configuring xml, errors such as missing letters and case often occur, which can not be checked, which reduces the development efficiency.

Using automatic assembly will avoid these errors and simplify the configuration.

Modify the bean configuration and add an attribute autowire = "byName"

<bean id="user" class="com.pag.pojo.User" autowire="byName">
    <property name="str" value="pag"/>
</bean>

Test again and the result is still output successfully!

We modify the bean id of cat to catXXX

Test again,
Execute null pointer java.lang.NullPointerException. Because the wrong set method is found according to the byName rule, the real setCat is not executed and the object is not initialized, so a null pointer error will be reported when calling.

Summary

When a bean node has an autowire byName attribute.

All set method names in its class, such as setCat, will be searched to obtain a string with set removed and lowercase, that is, cat.
Go to the spring container to find whether there is an object with this string name id.
If any, take out the injection; If not, a null pointer exception is reported.

byType

autowire byType

Using autowire byType first needs to ensure that objects of the same type are unique in the spring container. If it is not unique, a non unique exception will be reported. (NoUniqueBeanDefinitionException)

Modify the bean configuration of user: autowire = "byType"

<bean id="user" class="com.pag.pojo.User" autowire="byType">
    <property name="str" value="pag"/>
</bean>

Register a cat bean object!

<bean id="dog" class="com.pag.pojo.Dog"/>
<bean id="cat" class="com.pag.pojo.Cat"/>
<bean id="cat2" class="com.pag.pojo.Cat"/>
<bean id="user" class="com.pag.pojo.User" autowire="byType">
   <property name="str" value="pag"/>
</bean>

Test, error: NoUniqueBeanDefinitionException

Delete cat2 and change the bean name of cat! Test! Because it is assembled by type, no exception will be reported and the final result will not be affected. Even removing the id attribute does not affect the result.

Using annotations

jdk1.5 began to support annotations, and spring 2.5 began to fully support annotations.
Preparation: inject attributes by annotation.

xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

Enable attribute annotation support

<context:annotation-config/>

@Autowired

@Autowired is automatically transferred by type and does not support id matching.
Packages that need to be imported into spring AOP

Test class:

public class User {
    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;
    private String str;
    public Cat getCat() {
        return cat;
    }
    public Dog getDog() {
        return dog;
    }
    public String getStr() {
        return str;
    }
}

applicationContext.xml

<context:annotation-config/>
<bean id="dog" class="com.pag.pojo.Dog"/>
<bean id="cat" class="com.pag.pojo.Cat"/>
<bean id="user" class="com.pag.pojo.User"/>

be careful:
@Autowired(required=false) Description: false, the object can be null; true, the object must be saved and cannot be null.

//If the allowed object is null, set required = false, and the default is true
@Autowired(required = false)
private Cat cat;

Qualifier

  • @Autowired is automatically assembled according to the type. With @ Qualifier, it can be automatically assembled according to byName

  • @Qualifier cannot be used alone.

Modify the content of the configuration file to ensure that there are objects of type. And the name is not the default name of the class

<bean id="dog1" class="com.pag.pojo.Dog"/>
<bean id="dog2" class="com.pag.pojo.Dog"/>
<bean id="cat1" class="com.pag.pojo.Cat"/>
<bean id="cat2" class="com.pag.pojo.Cat"/>

No Qualifier test was added and an error was reported directly
Add a Qualifier annotation to the attribute

@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;

@Resource

@If the Resource has a specified name attribute, first search the assembly by name according to the attribute;
Secondly, assemble in the default byName mode;
If none of the above is successful, it will be assembled automatically by byType.
If they are not successful, an exception is reported.

Entity class:

public class User {
    //If the allowed object is null, set required = false, and the default is true
    @Resource(name = "cat2")
    private Cat cat;
    @Resource
    private Dog dog;
    private String str;
}

applicationContext.xml

<bean id="dog" class="com.pag.pojo.Dog"/>
<bean id="cat1" class="com.pag.pojo.Cat"/>
<bean id="cat2" class="com.pag.pojo.Cat"/>
<bean id="user" class="com.pag.pojo.User"/>

Delete cat2 from the configuration file and try again

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>

Only comments are retained in entity classes

@Resource
private Cat cat;
@Resource
private Dog dog;

Conclusion:
Search byName first, failed; The byType search is successful.

Summary

@Similarities and differences between Autowired and @ Resource:

  • @Both Autowired and @ Resource can be used to assemble bean s. Can be written on a field or on a setter method.
  • @Autowired is assembled by type by default (belonging to the spring specification). By default, dependent objects must exist. If null value is allowed, its required property can be set to false, such as @ Autowired(required=false). If we want to use name assembly, it can be used in combination with @ Qualifier annotation
  • @Resource (belonging to J2EE complex), which is assembled by name by default, and the name can be specified through the name attribute. If the name attribute is not specified, when the annotation is written on the field, the default is to take the field name to search by name. If the annotation is written on the setter method, the default is to take the attribute name for assembly. Assemble by type when no bean matching the name is found. However, it should be noted that once the name attribute is specified, it will only be assembled by name.
  • They have the same function. They inject objects by annotation, but the execution order is different@ Autowired byType first, @ Resource byName first.

Keywords: Java Spring ioc mvc bean

Added by jronyagz on Sat, 02 Oct 2021 00:39:52 +0300