Spring series 2: basic concepts and usage of spring containers

Content of this article

  1. Briefly review IoC and DI concepts
  2. Concept of Spring container
  3. xml configuration and initialization of
  4. Basic use of containers
  5. bean definition and initialization configuration

Simple understanding of IoC and DI concepts

What is IoC control reversal?

Generally speaking, but not strictly speaking, in the past, the traditional way was that the application needed an object, which was directly generated through new, and the management of the object was also controlled by the current program itself. Now there is a container, which is responsible for new all the objects required by the application. The objects are uniformly managed by this container. When the application needs objects, it directly asks the container for them. The application says I don't care how the objects come from. Anyway, just give them to me. This is different from the previous method. In the past, the application was created and managed by itself. Now it is handed over to the container for unified creation and management, and the control is reversed. This is simply understood as IoC.

What is DI dependency injection?

Generally speaking, but not strictly speaking, the object A required by the application depends on B. the container directly and automatically depends on B to object A, which can be understood as automatically injecting dependency B into A.

Spring's official description of these two concepts is rather convoluted, which is also attached here.

IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern.

IoC is also called dependency injection (DI). In this process, objects can only define their dependencies (that is, other objects they handle) through constructor parameters, factory method parameters, or properties set on the object instance after the object instance is constructed or returned from the factory method. The container then injects these dependencies when the bean is created. This process is essentially the inverse of the bean itself (hence the name "control inversion"), which controls the instantiation or location of dependencies by directly constructing classes

Concept and use of Spring container

The Spring IoC container is responsible for instantiating, configuring, and assembling bean s. The container obtains instructions about which objects to instantiate, configure, and assemble by reading the configuration metadata. Configuration metadata is represented in XML, Java annotations, or Java code.

Talk is cheap. Show me the code

Cut the crap and put the code here

The following will quickly demonstrate the simple use of the Spring container through a case.

Environmental preparation

IDE: IDEA

Maven: 3.5.6

JDK: java8

Create Maven project and introduce Spring dependency

pom files are as follows

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring-ioc-quickstart</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.verison>5.2.19.RELEASE</spring.verison>
    </properties>

    <dependencies>
        <!--Spring Context dependency-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.verison}</version>
        </dependency>
    </dependencies>

    <build>
        <!--Profile related-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
</project>

Create 2 simple classes A and B

A depends on B as follows

public class A {
    private B b;

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }
}

B as follows

public class B {
}

Create an XML configuration file for Spring

Create spring.com in the resources directory XML configuration file and configure bean s

<?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">

    <!--A Definition information of-->
    <bean id="a" class="com.crab.spring.A">
        <!--injection B Object dependency-->
        <property name="b" ref="b"/>
    </bean>

    <!--B Definition information of-->
    <bean id="b" class="com.crab.spring.B"></bean>
</beans>

Create a test class

public class MainTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        A a = context.getBean("a", A.class);
        B b = context.getBean("b", B.class);
        System.out.println("A Object:" + a);
        System.out.println("A Object B Dependency: " + a.getB() );
        System.out.println("B Object:" + b);
    }
}

Final file directory structure

Operation results

Objects AB are uniformly managed by the ClassPathXmlApplicationContext container, and are automatically injected by the container when A needs to rely on B. when the application needs to, it directly takes interfaces from the container, such as context getBean(),. It combines the concepts of IoC and DI. The above is the simple use of the Spring container.

A Object: com.crab.spring.A@2d928643
A Object B Dependency: com.crab.spring.B@5025a98f
B Object: com.crab.spring.B@5025a98f

Spring container object

BeanFactory interface

BeanFactory interface provides an advanced configuration mechanism that can manage any type of object. It is the root interface of Spring IoC container. The main definition methods are as follows.

package org.springframework.beans.factory;

public interface BeanFactory {
    // Get bean with specified name
    Object getBean(String name) throws BeansException;
    // Get bean by specifying name and type
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	// Get bean of specified type
	<T> T getBean(Class<T> requiredType) throws BeansException;
	// Is there a bean in the container
	boolean containsBean(String name);
    // Is it a single instance
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    
    //
}

It is highly recommended to read the notes on the source code of BeanFactory. It is very detailed and common interview: please describe the life cycle of Spring? There are very official and complete instructions on the notes

ApplicationContext interface

ApplicationContext interface is a sub interface of BeanFactory, which provides more enterprise level functions. It is responsible for instantiating, configuring and assembling beans, and supports bean configuration in xml configuration file, java annotation, java based and other ways. Implementation classes commonly used include ClassPathXmlApplicationContext, FileSystemXmlApplicationContext, AnnotationConfigApplicationContext, etc. they will be explained and used in detail later. Please keep reading with enthusiasm.

bean definition object

In Spring, the objects that make up an application and are managed by the Spring IoC container are called beans. These beans are created using the configuration metadata provided to the container, as defined in XML.

<!--A Definition information of-->
<bean id="a" class="com.crab.spring.A">
    <!--injection B Object dependency-->
    <property name="b" ref="b"/>
</bean>

The < bean / > configuration format and supporting elements in xml are as follows:

<bean id="myChild" class="com.crab.spring.demo02.ChildBean"
      init-method="init"
      destroy-method="destroy"
      name="childBean,aliasName"
      parent="myParent"
      scope="singleton"
      primary="true"
      depends-on="myParent"
      autowire="byType"
      autowire-candidate="true"
      factory-bean="myFactory"
      factory-method="getObj"
      abstract="false"
      ></bean>
element explain
id Unique ID
class Corresponding class, full path
name Support names. Multiple names can be separated by commas / semicolons / spaces. Multiple names can be used as aliases
init-method Custom initialization method
destroy-method The method by which the custom bean is destroyed
parent Specify parent class reference
scope Specify the scope, such as singleton and prototype, which will be described in detail later
primary It is mainly used to select when there are multiple bean s of the same type in the container during dependency injection
depends-on A reference that depends on another bean in the container
autowire Automatically inject dependencies by name or type
autowire-candidate Mark automatic dependency injection timing
factory-bean Specify the factory to create the bean
factory-method Specifies the factory method to create
abstract Is it abstract
lazy-init Delayed loading

Generally, if you do not explicitly specify the name, the default rule for Spring to generate the name is to convert the class name into a small hump to name the bean. For example, accountManager generates accountManager.

In the Spring container, the bean definition information is finally reflected through the interface BeanDefinition and its implementation class. BeanDefinition interface and abstract class AbstractBeanDefinition `, which are mainly defined as follows

package org.springframework.beans.factory.config;

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	void setParentName(@Nullable String parentName);
	void setBeanClassName(@Nullable String beanClassName);
	void setScope(@Nullable String scope);
	void setLazyInit(boolean lazyInit);
	void setDependsOn(@Nullable String... dependsOn);
	void setAutowireCandidate(boolean autowireCandidate);
	void setPrimary(boolean primary);
	void setFactoryBeanName(@Nullable String factoryBeanName);
	void setFactoryMethodName(@Nullable String factoryMethodName);
	void setInitMethodName(@Nullable String initMethodName);
	void setDestroyMethodName(@Nullable String destroyMethodName);
    // ellipsis
}

package org.springframework.beans.factory.support;

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
		implements BeanDefinition, Cloneable {
	private volatile Object beanClass;
	private String scope = SCOPE_DEFAULT;
	private boolean abstractFlag = false;
	private Boolean lazyInit;
	private int autowireMode = AUTOWIRE_NO;
	private String[] dependsOn;
	private boolean autowireCandidate = true;
	private boolean primary = false;
	private String factoryBeanName;
	private String factoryMethodName;
	private String initMethodName;
	private String destroyMethodName;
}

summary

This article mainly explains the concept of Ioc, demonstrates the rapid use of Spring Ioc container, and describes the bean definition elements in detail. The next article will talk about dependency injection of beans.

Source code of this article:

https://github.com/kongxubihai/pdf-spring-series/tree/main/spring-ioc-quickstart

Knowledge sharing, please indicate the source for reprint. There is no order in learning, the one who reaches is the first!

Keywords: Java

Added by 2oMst on Mon, 17 Jan 2022 04:03:03 +0200