Spring Notes: Automatic assembly of bean s

Keywords: Spring

Assembly refers to assigning attributes to objects. In addition to explicitly assigning attributes in xml files using the property tag, there are other ways to automatically assign attributes (assembly).

1. Auto-assemble using the autowire property of the bean tag.

The common values for the bean tag's autowire property are byName and byType, which also represent two different ways of automatic assembly. When autowire is byName, it looks for beans with the same name based on the object's attribute name, so this approach requires that the corresponding beans in the xml be unique. The byType looks for the corresponding bean based on the type of attribute, which must ensure that there is only one object of that type in the xml and that the corresponding bean tag can be found for assembly even if it does not have an id value set. The following is an example of automatic assembly using byName:

Cat class:

package com.yun.pojo;

public class Cat {
    public void shout(){
        System.out.println("I'm a Cat!");
    }
}

Dog class:

package com.yun.pojo;

public class Dog {
    public void shout(){
        System.out.println("I'm a Dog!");
    }
}

Person class:

package com.yun.pojo;

public class Person {
    private String name;
    private Dog dog;
    private Cat cat;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dog getDog() {
        return dog;
    }

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

    public Cat getCat() {
        return cat;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", dog=" + dog +
                ", cat=" + cat +
                '}';
    }
}

xml configuration:

<?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="cat" class="com.yun.pojo.Cat"/>
    <bean id="dog" class="com.yun.pojo.Dog"/>
    <!-- Configured autowire="byName"After that, Spring Will automatically find based on the property name id Same name bean Connect -->
    <bean id="person" class="com.yun.pojo.Person" autowire="byName">
        <property name="name" value="zhangsan"/>
<!-- The following are the uses property Label assignment, using autowire After auto-assembly, you do not need to configure the corresponding property Labeled -->
<!--        <property name="cat" ref="cat"/>-->
<!--        <property name="dog" ref="dog"/>-->
    </bean>
</beans>

Test:

import com.yun.pojo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = context.getBean("person", Person.class);
        person.getCat().shout();
        person.getDog().shout();
    }
}

2. Auto-assembly using annotations

Let me first list the basic classes that will be used in the example.

Cat class:

package com.yun.pojo;

public class Cat {
    public void shout(){
        System.out.println("I'm a Cat!");
    }
}

Dog class:

package com.yun.pojo;

public class Dog {
    public void shout(){
        System.out.println("I'm a Dog!");
    }
}

Test class:

import com.yun.pojo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person = context.getBean("person", Person.class);
        person.getCat().shout();
        person.getDog().shout();
    }
}

2.1 @Autowired

This annotation can be added to a class attribute. Generally speaking, the annotated attribute is another bean, so the attribute name and the id value of the bean should be the same, which is actually a combination of byName and byType. In addition, the @Autowired comment can pass in a parameter, and @Autowired(required = false) indicates that this property can be null. The extensions that need to be added to the xml to use this annotation are:

  • xmlns:context="http://www.springframework.org/schema/context"
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd
  • <context:annotation-config/>

xml configuration:

<?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
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- Don't forget this extension and the three above extensions, or the annotations won't work -->
    <context:annotation-config/>

    <bean id="cat" class="com.yun.pojo.Cat"/>
    <bean id="dog" class="com.yun.pojo.Dog"/>
    <bean id="person" class="com.yun.pojo.Person"/>
</beans>

Person class:

package com.yun.pojo;

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

public class Person {
    private String name;
    @Autowired  // The annotated property name needs to be consistent with the bean's id
    private Dog dog;
    @Autowired  // @Autowired(required = false), indicating that this property can be null.
    private Cat cat;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dog getDog() {
        return dog;
    }

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

    public Cat getCat() {
        return cat;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", dog=" + dog +
                ", cat=" + cat +
                '}';
    }
}

2.2 @Nullable

Indicates that the annotated property can be null.

package com.yun.pojo;

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

public class Person {
    private String name;
    @Autowired
    private Dog dog;
    @Autowired
    private Cat cat;

    public Person() {
    }

    // @Nullable indicates that this property can be null when an incoming parameter is passed in
    public Person(@Nullable String name) {
        this.name = name;
    }
}

2.3 @Qualifier

When multiple beans are configured in one xml for the same class, you can use the @Qualifier annotation to specify a specific bean.

public class Person {
    private String name;
    @Autowired
    @Qualifier(value = "dog2")  // @Qualifier is used to specify a specific bean
    private Dog dog;
    @Autowired
    private Cat cat;
}

2.3 Other common notes

To use the following comment, you need to add <context:component-scan base-package="com.yun.pojo"/> to the xml.

<?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
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- Specify the need for sweeping Spring Annotated Package -->
    <context:component-scan base-package="com.yun"/>
    <context:annotation-config/>

</beans>

@Component/@Controller/@Service/@Repository

These annotations need to be added to the bean class, which is equivalent to configuring the corresponding beans in the xml, indicating that the class is managed by Spring. The functions of these annotations are the same, except in different scenarios, @Component is used in the pojo package, @Controller/@Service/@Repository is used in the controller, service, and dao of the MVC three-tier architecture.

Java class:

package com.yun.pojo;

import org.springframework.stereotype.Component;

// The @Component annotation corresponds to the <bean id="user" class="com.yun.pojo.User"/>
// The automatically generated bean object name is lowercase for the class name
@Component
public class User {
    private String name = "zhangsan";

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

@Value

Configure attribute values.

package com.yun.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class User {
    // @Value is equivalent to <property name="name" value="zhangsan"/>in xml configuration
    // If the property has a corresponding set method, this comment can also be applied to set methods
    @Value("zhangsan")
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

@Scope

The scope attribute, which is equivalent to the bean tag in xml, can be assigned by a parameter.

package com.yun.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;


@Component
@Scope("singleton")
public class User {
    @Value("zhangsan")
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

2.4 xml configuration class

In addition to xml configuration, Spring configuration information can also be configured using the Spring configuration class, which is equivalent to xml configuration. With the Spring configuration class, xml configuration is not needed. Examples of use are as follows:

Ordinary Java classes: They are used the same way as xml is configured.

package com.yun.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class User {
    @Value("zhangsan")
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

Spring Configuration Class: The functions of the xml configuration are available in the configuration class, but only through annotations.

package com.yun.config;

import com.yun.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

// The configuration class for the @Configuration annotation is also managed by Spring because it is also annotated by @Component itself
// Configuration classes work the same way as Spring's xml configuration files, or are used instead of xml configuration files.
@Configuration
// After being annotated by @ComponentScan, you can also specify the directory to scan, which is equivalent to <context:component-scan base-package="com.yun"/>
@ComponentScan("com.yun.pojo")
// Importing other Spring configuration classes is equivalent to <import resource="beans2.xml"/>in XML configuration
@Import(BeanConfig2.class)
public class BeanConfig {

    // @Bean is used on the get method, which is equivalent to <bean id="getUser" class="com.yun.pojo.User"/>in the xml configuration
    // Note that the id attribute value of the bean tag is the method name
    @Bean
    public User getUser(){
        return new User();
    }
}

Test:

import com.yun.config.BeanConfig;
import com.yun.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyTest {
    public static void main(String[] args) {
        // By using Spring to configure classes, you need to use AnnotationConfigApplicationContext instead of ClassPathXmlApplicationContext
        ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig .class);
        // Get object from method name
        User user = context.getBean("getUser", User.class);
        System.out.println(user);
    }
}

Posted by rockroka on Thu, 02 Dec 2021 12:09:03 -0800