Automatic assembly of spring bean

Posted by VnVision on Mon, 17 Jan 2022 06:39:05 +0100

1. Assemble manually and prepare the test environment

1.1 create three entity classes

public class Dog {
    public void shout(){
        System.out.println("Woof");
    }
}
public class Cat {
    public void shout(){
        System.out.println("Meow meow");
    }
}

People class needs to add get, set and toString methods

public class People {
    private String name;
    private Dog dog;
    private Cat cat;
}

1.2 writing spring configuration files

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="cat" class="com.lv.pojo.Cat"/>
    <bean id="dog" class="com.lv.pojo.Dog"/>

    <bean id="people" class="com.lv.pojo.People">
        <property name="name" value="Little bastard"/>
        <property name="dog" ref="dog"/>
        <property name="cat" ref="cat"/>
    </bean>
</beans>

1.3 testing

@Test
public void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    People people = context.getBean("people", People.class);
    people.getCat().shout();
    people.getDog().shout();
}

1.4 implementation results

2 automatic assembly

2.1 use profile

2.1.1 byName auto assemble by name

When modifying the configuration file, byName will automatically find the Bean id corresponding to the value behind the set method of its own object in the container context

<bean id="cat" class="com.lv.pojo.Cat"/>
<bean id="dog1" class="com.lv.pojo.Dog"/>

<bean id="people" class="com.lv.pojo.People" autowire="byName">
    <property name="name" value="Little bastard"/>
</bean>

After the test, the output is successful, and the test results are the same as above

Note: the id of the Bean must be the same as the value after the set method name of its own object. For example, for the setCat() method, the id of the Bean must be written as cat, otherwise a null pointer exception will be reported if it is not found

2.1.2 byType automatic assembly by type

When modifying the configuration file, byType will automatically find beans with the same object properties in the container context, and deleting the Bean id will not affect the result

<bean class="com.lv.pojo.Cat"/>
<bean class="com.lv.pojo.Dog"/>

<bean id="people" class="com.lv.pojo.People" autowire="byType">
    <property name="name" value="Little bastard"/>
</bean>

After the test, the output is successful, and the test results are the same as above

Note: beans with the same class are not allowed in this way, because if there are beans with the same type, spring cannot determine which one we need, and will report a NoUniqueBeanDefinitionException

2.2 use notes (recommended)

2.2.1 preparation

2.2.1.1 add a context constraint in the file header of the spring configuration file

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

2.2.1.2 enable annotation support

<context:annotation-config/>

2.2.1.3 modified 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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:annotation-config/>

    <bean id="cat555" class="com.lv.pojo.Cat"/>
    <bean id="dog" class="com.lv.pojo.Dog"/>
    <bean id="people" class="com.lv.pojo.People"/>
</beans>

2.2.2 @Autowired 

byType assembly attribute is used by default. If the type is the same, it will be assembled according to byName. If the name does not match, an error beandefinitionparsengexception will be reported

2.2.2.1 application method

Add @ Autowired annotation on the attribute to be assembled in the entity class. The @ Autowired annotation assembly attribute does not need a set method. If there is a set method, it can also be written on the set method

@Autowired
private Dog dog;
@Autowired
private Cat cat;

After the test, the output is successful, and the test results are the same as above

2.2.2.2 required parameters

@Autowired has a parameter required. The default value is true, which means that the property cannot be null and must have an object. That is, after @ Autowired is added to a property, the corresponding Bean must be configured in the spring configuration file, otherwise an error will be reported. If required = false is manually set, this property is allowed to be null

@Autowired(required = false)
private Cat cat;

2.2.3 @Qualifier

It is usually used in combination with @ Autowired. When there are multiple beans with duplicate class types, you can name the attribute to control which Bean @ Autowired uses when assembling by byName

2.2.3.1 modifying the spring configuration file

<bean id="cat111" class="com.lv.pojo.Cat"/>
<bean id="cat222" class="com.lv.pojo.Cat"/>
<bean id="cat333" class="com.lv.pojo.Cat"/>

2.2.3.2 add @ Qualifier annotation

@Autowired
@Qualifier(value = "cat222")
private Cat cat;

After the test, the output is successful, and the test results are the same as above

2.2.4 @Resource

It's not spring's annotation, it's java's own

import javax.annotation.Resource;

@The Resource is first assembled by byName. If the Bean whose id corresponds to the attribute name is not found, then it is assembled by byType. If multiple beans with duplicate class types are found, an error NoUniqueBeanDefinitionException is reported

2.2.4.1 application method

Add @ Resource annotation to the attribute to be assembled in the entity class. The @ Resource annotation assembly attribute does not need a set method. If there is a set method written on the set method, the default attribute name is used if the name is not given. If the name is given, it needs to be followed by a name parameter in the @ Resource annotation

2.2.4.1.1 adding notes

@Resource(name = "dog111")
private Dog dog;

2.2.4.1.2 spring configuration file

<bean id="dog111" class="com.lv.pojo.Dog"/>
<bean id="dog222" class="com.lv.pojo.Dog"/>

After the test, the output is successful, and the test results are the same as above