Learn more about understanding Bean autowiring

“This is the 19th day of my participation in the First Challenge 2022, for more details: First Challenge 2022”.

About the author

  • The authors introduce

🍓 Blog home Page: author home page 🍓 Introduction: High-quality creator in the JAVA field 🥇, a junior student 🎓, participated in various provincial and national competitions during school, and won a series of honors 🍓, Ali Cloud expert blogger, 51CTO expert blogger, follow me: Pay attention to my learning materials, document download all have, regularly update the article every day, inspirational to do a JAVA senior program ape 👨💻


9, Bean automatic assembly

  • Autowiring is one way to use Spring to satisfy bean dependencies

  • Spring finds the dependent beans for a bean in the application context.

There are three assembly mechanisms for beans in Spring:

  1. Explicitly configured in XML;

  2. Explicitly configured in Java;

  3. Implicit bean discovery mechanisms and autowiring.

Here we focus on the third type: automated assembly beans.

Spring autowiring needs to be done from two perspectives, or two operations:

  1. Component scanning: Spring automatically discovers beans created in the application context;

  2. Autowiring: Spring automatically satisfies dependencies between beans, known as IoC/DI;

The combination of component scanning and auto-assembly is powerful enough to minimize the configuration of the display.

Recommendation: Use annotations instead of auto-assemble XML configuration.

9.1 Environment Construction

  1. Create a new project
  2. Create two new entity classes,Baoma BenchiThere is a method called
package com.autowired.pojo;

/ * * *@ProjectName: Spring5study
 * @Package: com.autowired.pojo
 * @ClassName: Baoma
 * @Author: Shengrui Zhang *@Date: 2022/2/5 and *@Version: 1.0 * /
public class Baoma {
    public void name(a){
        System.out.println("BMW W, beyond electric."); }}Copy the code
package com.autowired.pojo;

/ * * *@ProjectName: Spring5study
 * @Package: com.autowired.pojo
 * @ClassName: Benchi
 * @Author: Shengrui Zhang *@Date: 2022/2/5 and *@Version: 1.0 * /
public class Benchi {
    public void name(a){
        System.out.println("Mercedes, Mercedes."); }}Copy the code

3. Create a User User entity class

package com.autowired.pojo;

/ * * *@ProjectName: Spring5study
 * @Package: com.autowired.pojo
 * @ClassName: User
 * @Author: Shengrui Zhang *@Date: 2022/2/5 regained their *@Version: 1.0 * /
public class User {
    private Benchi benchi;
    private Baoma baoma;
    private String desc;

    public Benchi getBenchi(a) {
        return benchi;
    }

    public void setBenchi(Benchi benchi) {
        this.benchi = benchi;
    }

    public Baoma getBaoma(a) {
        return baoma;
    }

    public void setBaoma(Baoma baoma) {
        this.baoma = baoma;
    }

    public String getDesc(a) {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc; }}Copy the code

4. Write the Spring 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">

    <bean id="baoma" class="com.autowired.pojo.Baoma"/>
    <bean id="benchi" class="com.autowired.pojo.Benchi"/>

    <bean id="user" class="com.autowired.pojo.User">
        <property name="baoma" ref="baoma"/>
        <property name="benchi" ref="benchi"/>
        <property name="desc" value="changzhang"/>
    </bean>
</beans>
Copy the code

5. The test class

import com.autowired.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/ * * *@ProjectName: Spring5study
 * @Package: PACKAGE_NAME
 * @ClassName: MyTest
 * @Author: Shengrui Zhang *@Date: 2022/2/5 men *@Version: 1.0 * /
public class MyTest {
    @Test
    public void test1(a){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = (User) context.getBean("user"); user.getBenchi().name(); user.getBaoma().name(); }}Copy the code

9.2 byName

Autowire byName (automatic assembly byName)

During the manual configuration of XML, errors such as missing letters and case often occur and cannot be checked, which reduces the development efficiency.

Using autowiring will avoid these errors and simplify the configuration. Testing:

  1. Modify bean configuration by adding a property autowire=”byName”

      
<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="baoma" class="com.autowired.pojo.Baoma"/>
    <bean id="benchi" class="com.autowired.pojo.Benchi"/>

    <bean id="user" class="com.autowired.pojo.User" autowire="byName">
        <property name="desc" value="changzhang"/>
    </bean>
</beans>
Copy the code

2. Test again, the result is still successfully output!

3. We changed the bean ID of Beichi to benchiXXX

  1. Test again, the execution times null pointer Java lang. NullPointerException. Because the byName rule does not correspond to the set method, the real setBenchi is not executed and the object is not initialized, so the null pointer error is reported when the call is made.

Summary:

When a bean node has the property Autowire byName.

  1. It looks for all set method names in its class, such as setBenchi, to get the string with set removed and its initial lowercase, benchi.

  2. Go to the Spring container and look for an object with the string name ID.

  3. If so, remove and inject; If not, a null pointer exception is reported.

9.3 、byType

Autowire byType (automatic assembly byType)

Using Autowire byType requires that objects of the same type are unique in the Spring container. If not the only, will report not only abnormal NoUniqueBeanDefinitionException.

Testing:

1. Modify user’s bean configuration:

<bean id="user" class="com.autowired.pojo.User" autowire="byType">
    <property name="desc" value="changzhang"/>
</bean>
Copy the code

  1. Test, normal output

  1. Register a Beichi bean object!
<bean id="baoma" class="com.autowired.pojo.Baoma"/>
<bean id="benchi" class="com.autowired.pojo.Benchi"/>
<bean id="benchi2" class="com.autowired.pojo.Benchi"/>

<bean id="user" class="com.autowired.pojo.User" autowire="byType">
    <property name="desc" value="changzhang"/>
</bean>
Copy the code

4. Test error: UnsatisfiedDependencyException

5. Delete benchi2 and rename benchi bean! The test! Because it is assembled by type, no exceptions are reported and the final result is not affected. Even removing the ID attribute does not affect the results.

This is auto-assemble by type!

9.4 Using Annotations

Preparation: Inject properties using annotations.

  1. inspringImported into the configuration filecontextThe file header

      
<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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
Copy the code

2. Enable attribute annotation support!

<context:annotation-config/>
Copy the code

9.4.1 @Autowired

  • @autoWired is automatically configured by type and does not support ID matching.
  • Need to import the spring-AOP package!

Testing:

  1. willUserIn the classsetMethod is removed and used@Autowiredannotations
package com.autowired.pojo;

import org.springframework.beans.factory.annotation.Autowired;

/ * * *@ProjectName: Spring5study
 * @Package: com.autowired.pojo
 * @ClassName: User
 * @Author: Shengrui Zhang *@Date: 2022/2/5 regained their *@Version: 1.0 * /
public class User {
    @Autowired
    private Benchi benchi;
    @Autowired
    private Baoma baoma;
    private String desc;

    public Benchi getBenchi(a) {
        return benchi;
    }
    
    public Baoma getBaoma(a) {
        return baoma;
    }
    

    public String getDesc(a) {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc; }}Copy the code

2. Configure the content of the file


      
<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 http://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="baoma" class="com.autowired.pojo.Baoma"/>
    <bean id="benchi" class="com.autowired.pojo.Benchi"/>
    <bean id="user" class="com.autowired.pojo.User"/>

</beans>
Copy the code

3. Test, output results successfully!

【 Popular Science Class 】

@autoWired (Required =false) True, object must hold object, cannot be null.

// If null is allowed, set required = false, which defaults to true
@Autowired(required = false)
private Benchi benchi;
Copy the code

9.4.2 @ the Qualifier

  • @autowired is automatically assembled by type, and @quali fier is automatically assembled by way of byName
  • @quali fier Cannot be used alone

Test procedure:

1. Configure the modification content of the file to ensure that the type of the file contains objects. And the name is not the default name of the class

<bean id="baoma1" class="com.autowired.pojo.Baoma"/>
<bean id="baoma2" class="com.autowired.pojo.Baoma"/>
<bean id="benchi1" class="com.autowired.pojo.Benchi"/>
<bean id="benchi2" class="com.autowired.pojo.Benchi"/>
<bean id="user" class="com.autowired.pojo.User"/>
Copy the code

2. No Gaquali fier test, direct error reporting

3. Add Qualifier annotations to attributes

package com.autowired.pojo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

/ * * *@ProjectName: Spring5study
 * @Package: com.autowired.pojo
 * @ClassName: User
 * @Author: Shengrui Zhang *@Date: 2022/2/5 regained their *@Version: 1.0 * /
public class User {
    @Autowired
    @Qualifier(value = "benchi2")
    private Benchi benchi;
    @Autowired
    @Qualifier(value = "baoma1")
    private Baoma baoma;
    private String desc;

    public Benchi getBenchi(a) {
        return benchi;
    }

    public Baoma getBaoma(a) {
        return baoma;
    }


    public String getDesc(a) {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc; }}Copy the code

4. Test, successful output!

9.4.3 @ the Resource

  • @ResourceIf specifiednameProperty, according to the property firstbyNameWay to find assembly;
  • And then the defaultbyNameAssembly;
  • If all else fails, pressbyTypeThe way of automatic assembly.
  • If none is successful, an exception is reported.

Entity class User

package com.autowired.pojo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import javax.annotation.Resource;

/ * * *@ProjectName: Spring5study
 * @Package: com.autowired.pojo
 * @ClassName: User
 * @Author: Shengrui Zhang *@Date: 2022/2/5 regained their *@Version: 1.0 * /
public class User {
    @Resource(name = "benchi2")
    // If null is allowed, set required = false, which defaults to true
    private Benchi benchi;
    @Resource
    private Baoma baoma;
    private String desc;

    public Benchi getBenchi(a) {
        return benchi;
    }

    public Baoma getBaoma(a) {
        return baoma;
    }


    public String getDesc(a) {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc; }}Copy the code

beans.xml


      
<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 http://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="baoma" class="com.autowired.pojo.Baoma"/>
    <bean id="benchi1" class="com.autowired.pojo.Benchi"/>
    <bean id="benchi2" class="com.autowired.pojo.Benchi"/>
    <bean id="user" class="com.autowired.pojo.User"/>

</beans>
Copy the code

Test result: Result output successfully!

Delete benchi2 from beans.xml configuration file

<bean id="baoma" class="com.autowired.pojo.Baoma"/>
<bean id="benchi1" class="com.autowired.pojo.Benchi"/>
<bean id="user" class="com.autowired.pojo.User"/>
Copy the code

Only the @resouce annotation remains on the entity class

    @Resource
    // If null is allowed, set required = false, which defaults to true
    private Benchi benchi;
    @Resource
    private Baoma baoma;
    private String desc;
Copy the code

Test result: Successful output!

Conclusion: byName lookup fails; The byType search succeeds.

9.5 summarize

@autowired and @resource

  1. Both @autoWired and @Resource can be used to assemble beans. You can write it on a field, or you can write it on a setter method.

  2. @autoWired by default assembs by type (belonging to the Spring specification). By default, dependent objects must be required to exist. To allow null values, you can set its required property to false, as in: @autowired (required=false), which we can use in conjunction with @quali fier annotations if we want to use name assembly

  3. @resource (belongs to J2EE return), which is assembled by name by default, which can be specified by the name attribute. If the name attribute is not specified, the annotation defaults to the field name for lookup by name when written on a field, or the attribute name when written on a setter method for assembly. Assemble by type when no bean matching the name can be found. Note, however, that if the name attribute is specified, it will only be assembled by name.

They do the same thing: they annotate objects, but in a different order. @autoWired first byType, @resource first

ByName.

After the language

The original intention of the director to write blog is very simple, I hope everyone in the process of learning less detours, learn more things, to their own help to leave your praise 👍 or pay attention to ➕ are the biggest support for me, your attention and praise to the director every day more power.

If you don’t understand one part of the article, you can reply to me in the comment section. Let’s discuss, learn and progress together!