[springboot annotation container] @ Bean

@Bean
The @ Configuration annotation mentioned earlier is equivalent to turning a class into spring Configuration xml, how to inject beans with Configuration files? This requires the annotation @ Bean, which is used for methods. Adding @ Bean to a method is equivalent to adding a < Bean > tag to xml.

Let's take a look at an example first, and then introduce it in detail

public class Person {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Person{" +"name='" + name + '\'' +'}';
    }
}
package com.lhb.config;

import com.lhb.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration // It is equivalent to writing an xml configuration file of spring
public class MyConfig {
    @Bean // It is equivalent to registering a bean in the bean tag in the xml configuration file. The type is the return value type, and the id is the method name by default
    public Person person(){
        // It is equivalent to configuring attributes for the object of bean tag in xml
        Person person = new Person();
        person.setName("john");
        return person;
    }
}
package com.lhb;

import com.lhb.bean.Person;
import com.lhb.config.MyConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AppliactionRunner {
    public static void main(String[] args) {
// When using annotations, you need to use AnnotationConfigApplicationContext, which will put the return objects of @ Bean annotation in the class of @ Configuration annotation into the container.
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        Person person = applicationContext.getBean(Person.class);
        System.out.println(person); // Person{name='john'}
    }
}

We know that in the past, when using xml to configure beans, beans will have id and name. When we use @ Bean annotation, the name of the default method is the name of the Bean. Take the following example:

@Configuration // It is equivalent to writing an xml configuration file of spring
public class MyConfig {
    @Bean
    public Person person(){
        // It is equivalent to configuring attributes for the object of bean tag in xml
        Person person = new Person();
        person.setName("john");
        return person;
    }

    @Bean
    public Person person01(){
        // It is equivalent to configuring attributes for the object of bean tag in xml
        Person person = new Person();
        person.setName("john");
        return person;
    }
}
public class AppliactionRunner {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] names = applicationContext.getBeanNamesForType(Person.class);
        for (String name : names) {
            System.out.println(name); // person person01
        }
    }
}

Through the getBeanNamesForType() method, we can only use the name of a type of Bean injected into the container. As we said earlier, the default value of this name is the name of the method where @ Bean is located. Because we have defined two beans, we finally print two names.

So what if you don't want the name of this method to be the default name value of the Bean? One way is to modify the method name directly. The other way can be set in the @ Bean annotation, as follows:

Method 1: modify the name value of the bean by modifying the method name

@Configuration // It is equivalent to writing an xml configuration file of spring
public class MyConfig {
    @Bean
    public Person person01(){
        // It is equivalent to configuring attributes for the object of bean tag in xml
        Person person = new Person();
        person.setName("john");
        return person;
    }
}
public class AppliactionRunner {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] names = applicationContext.getBeanNamesForType(Person.class);
        for (String name : names) {
            System.out.println(name); //person01
        }
    }
}

Method 2: modify through @ Bean annotation

@Configuration
public class MyConfig {
    @Bean("personName")
    public Person person(){
        Person person = new Person();
        person.setName("john");
        return person;
    }
}
public class AppliactionRunner {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] names = applicationContext.getBeanNamesForType(Person.class);
        for (String name : names) {
            System.out.println(name);// personName
        }
    }
}

Let's take a look at the functions of other attributes in @ Bean:

Example 1: inject two bean s of the same type, but one uses the value attribute

package com.lhb.config;

import com.lhb.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration // It is equivalent to writing an xml configuration file of spring
public class MyConfig {
    @Bean(value = { "person1"})
    public Person person(){
        // It is equivalent to configuring attributes for the object of bean tag in xml
        Person person = new Person();
        person.setName("john");
        return person;
    }

    @Bean
    public Person person1(){
        // It is equivalent to configuring attributes for the object of bean tag in xml
        Person person = new Person();
        person.setName("john1");
        return person;
    }
}

Run the main method

public class AppliactionRunner {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        System.out.println(applicationContext.getBean(Person.class));
        String[] names = applicationContext.getBeanNamesForType(Person.class);
        for (String name : names) {
            System.out.println(name);
        }
    }
}

Print run results:

We can see that the final Bean uses the value attribute. We know that we need to modify the value of its name attribute for a Bean, either through the method name or by using the value or name attribute in @ Bean. Here, our colleagues use the method in 2 to change the name to the same name, and find that the value is ultimately used, which is similar to that when multiple beans are set in xml, when the primary attribute is set in which Bean, which will eventually be used.
Also note: the name and value attributes in @ Bean cannot be used at the same time. Only one can be used.

Instance 2: init method attribute of @ Bean

package com.lhb.bean;

import org.springframework.beans.factory.InitializingBean;

public class Person implements InitializingBean {
    private String name;
    public Person(String name) {
        System.out.println("i am constructor");
        this.name = name;
    }
    public void initMehod(){System.out.println("i am init.....");}

    // InitializingBean interface method
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("i am InitalizaingBean's afterPropertiesSet");
    }

    @Override
    public String toString() { return "Person{" +"name='" + name + '\'' +'}'; }
}
@Configuration // It is equivalent to writing an xml configuration file of spring
public class MyConfig {
    @Bean(initMethod="initMehod")
    public Person person(){
        Person person = new Person("john");
        return person;
    }
}
public class AppliactionRunner {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        System.out.println(applicationContext.getBean(Person.class));
        String[] names = applicationContext.getBeanNamesForType(Person.class);
        for (String name : names) {
            System.out.println(name);
        }
    }
}

Operation results:

You can see that the initmethod method will be executed after instantiation. Here I also added an InitializationBean interface, so you can observe their execution order.

Keywords: Java Spring Spring Boot Container

Added by gutogouveia on Wed, 23 Feb 2022 16:50:50 +0200