Spring - Assembling Beans

basic assembly

Piecing together beans within a Spring container is called assembly. When assembling beans, you need to tell which beans and how the container uses dependency injection to tie them together.

Assembly using XML

XML is the most common source of configuration for Spring applications.

Several Spring containers support the use of XML to wire up beans, including:

  1. XmlBeanFactory: Call ClassPathResource to load the context definition file (such as applicationContext.xml).

  2. ClassPathXmlApplicationContext: Load the context definition file from the classpath.

  3. XmlWebApplicationContext: Load the definition file from the Web application context.

An example of a configuration file is as follows:

<?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="student" class="com.gavin.ioc.Student" scope="singleton">
    <property name="name" value="Gavin"/>
</bean>
</beans>
  • The root element of the context definition file is beans, and there are multiple bean child elements. Each bean element defines how a bean is wired into the Spring container.
  • The most basic configuration for a bean includes the bean's ID and the bean's full class name.

scope

Several scope property values: prototype, singleton, request, session, global-session. Beans in Spring are singleton by default. Always returns an instance. If you want to return a different instance, you need to define the prototype mode.

scope describe
singleton One bean definition corresponds to one object instance in each Spring IoC container
prototype A bean definition corresponds to multiple instances
request In an HTTP request, a bean definition corresponds to an object 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 context of a Web-based Spring Application.
session In an HTTP Session, a Bean definition corresponds to an object instance. This scope is only valid in the context of a Web-based Spring Application.
global-session In a global HTTP Session, a bean definition corresponds to an object instance. Typically, this only works when using the portlet context. This scope is only valid in the context of a Web-based Spring Application.

Using a prototype bean will have a performance impact, try not to set it to prototype unless it is necessary.

instantiate and destroy

When Spring instantiates a bean or destroys a bean, it sometimes needs to do some processing work, so Spring can call the two life cycle methods of the bean when creating and tearing down the bean, namely init-methodmethod and destory-methodmethod


Spring also provides two interfaces to achieve the same functionality: InitializingBeanand DisposableBean. InitializingBeanAn interface provides a afterPropertiesSet()method. DisposableBeanInterfaces provide destroy()methods.

But these two interfaces are deprecated, it will bind the bean with the Spring API.

Inject dependencies through the set method

The property sub-elements of the bean element specify injection using their set method. Anything can be injected, from primitive types to collection classes and even application system beans.

inner bean

Configure a bean inside the property, then the bean can only be referenced by the property. and cannot be referenced by other properties.

<bean id="outside" class="...">
    <property name="emp">
       <bean id="inside" class="...">
           <property name="" value=""/>
       </bean>
    </property>
</bean>

As shown in the above example, the emp attribute refers to the inside bean, where the inside bean can only be referenced by the emp attribute, and other attributes cannot be referenced.

inherited configuration

The Graduate class inherits the Student class with the following properties:

public class Student {
    protected int age;
    protected String name;
    ...
}
public class Graduate extends Student {
    private String degree;
    ...
}

The configuration is as follows:

<!--配置一个学生-->
<bean id="student" class="com.gavin.inherit.Student">
    <property name="age" value="18"/>
    <property name="name" value="Gavin"/>
</bean>
<bean id="graduate" parent="student" class="com.gavin.inherit.Graduate">
    <!--如果单独再配置name和age,则会覆盖从父对象继承的这个属性的值-->
    <property name="age" value="20"/>
    <property name="name" value="XiaoMing"/>
    <property name="degree" value="学士"/>
</bean>

Inject values ​​into collection properties

The configuration for injecting values ​​into an array or List collection is as follows:

Department has three properties:

private String name;
private String[] empName;
private List employeeList;
<property name="empName">
    <list>
        <value>小明</value>
        <value>小红</value>
        <value>小亮</value>
    </list>
</property>
<property name="employeeList">
    <list>
        <ref bean="employee"/>
        <ref bean="employee1"/>
        <ref bean="employee2"/>
    </list>
</property>

The injection to the Set collection is similar:

<property name="employeeSet">
    <set>
        <ref bean="employee"/>
        <ref bean="employee1"/>
        <ref bean="employee2"/>
        <ref bean="employee2"/>
        <ref bean="employee2"/>
    </set>
</property>

Inject values ​​into Map properties

The injection of Map is similar, but a little more complicated:

Add Map property to Department:

private Map employeeMap;

The configuration in Spring is as follows:

<property name="employeeMap">
    <map>
        <entry key="1" value-ref="employee"/>
        <entry key="2" value-ref="employee1"/>
        <entry key="3" value-ref="employee2"/>
    </map>
</property>

inject null

<property name="barlist">
    <null/>
</property>

Injecting dependencies through constructors

The Employee object is as follows:

public class Employee {
    private String name;
    private int age;

    public Employee() {
    }

    public Employee(String name, int age) {
        System.out.println("Employee(String name, int age)函数被调用");
        this.name = name;
        this.age = age;
    }

    public Employee(String name) {
        System.out.println("Employee(String name)函数被调用");
        this.name = name;
    }
}

Configuration file:

<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">
    <!--配置一个Employee对象-->
    <bean id="employee" class="com.gavin.constructor.Employee">
        <!--通过构造函数来注入-->
        <constructor-arg index="0"  value="Gavin"/>
        <constructor-arg index="1"  value="19"/>
    </bean>
</beans>

That is, you can pass arguments to the constructor by configuring the constructor-arg element under the bean element. index is used to specify the position of the parameter.

The disadvantage of set injection is that it cannot clearly express which properties are required and which are optional. The advantage of construction injection is that it enforces dependencies by construction, and it is impossible to instantiate incomplete or unusable beans.

If the property is of object type, use ref=""

Autowire Bean property values

<bean id="foo" class="...Foo" autowire="autowire type">

There are four types of autowiring:

  1. byName: Look for a bean with the same name as the attribute. If it is not found, it cannot be installed.
  2. byType: Looking for a bean of the same type as the attribute, can't find it, can't install it, and find multiple throw exceptions
  3. constructor: Find one or more beans that are consistent with the bean's construction parameters. If no or more than one is found, an exception is thrown. Match according to the type of the parameter.
  4. autodetect: Choose between (3) and (2). The handling of uncertainty is consistent with (3) and (2). [3 and 2 are in order!
  5. default: This needs to be configured in beans default-autowire="指定". When default-autowired is specified in beans, the default autowire mode of all beans is the specified assembly mode.
  6. no: do not autowire, this is the default value of autowire

    • The case of byName:
public class Dog {
    private String name;
    private int age;
    ...
}

public class Master {
    private String name;
    private Dog dog;
    ...
}

There is a Dog object in the Master, and the configuration is as follows:

<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">
    <!--Master对象-->
    <bean id="master" class="com.gavin.autowire.Master" autowire="byName">
        <property name="name" value="Gavin"/>
    </bean>
    <!--Dog对象-->
    <bean id="dog" class="com.gavin.autowire.Dog">
        <property name="name" value="大黄"/>
        <property name="age" value="2"/>
    </bean>
</beans>

It can be seen that the dog object is not referenced in the master, but the attribute autowire=byName is set. At this time, the Spring container will search according to the attribute name. After finding the object whose attribute name is dog, it will be automatically assembled.

Others are similar. For example, byType searches by type, so no matter what the property name of the Dog object is, as long as a Dog object can be found, it can be automatically assembled. But if more than one Dog object is found, an exception will be thrown.

  • In the case of constructor, you need to write a constructor with only Dog parameter in Master, then the Spring container will pass the configured Dog object to this constructor.
public class Master {
    private String name;
    private Dog dog;

    public Master(Dog dog){
        this.dog = dog;
    }
    ...
}

The configuration is as follows:

<bean id="master" class="com.gavin.autowire.Master" autowire="constructor">
        <property name="name" value="Gavin"/>
</bean>
<!--Dog对象-->
<bean id="dog" class="com.gavin.autowire.Dog">
    <property name="name" value="大黄"/>
    <property name="age" value="2"/>
</bean>

[Note]: Automatic assembly can be used without it! Because autowiring doesn't have set injection or constructor injection explicitly.

Using Spring Special Beans

Let Spring treat these beans specially, so that they can:
1. Process beans after configuration, which involves the life cycle of beans and bean factories. (such as BeanPostProcessor, etc.)

2. Change dependency injection to convert strings to other types

3. Load information from attribute text, including information internationalization

4. Monitor and process system messages issued by other beans and Spring

5. Know your unique identity in Spring.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325655124&siteId=291194637