Spring drive automatic assembly annotation (c)

A, @ Autowired automatic assembly operation yl

New Person assembly, and to assign attribute name is "Joe Smith", age 30 property assignment.

package com.example.demo.annotation;

import lombok.Data;
import org.springframework.stereotype.Component;

@Data
@Component
public class Person {
    public  String name="张三";
    
    public  Integer age=30;
    
    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    public Person() {
    }
}

Testing unit assembly for automatic assembly Person @Autowired.

package com.example.demo;

import com.example.demo.annotation.MainConfig;
import com.example.demo.annotation.Person;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
class annotationTest {

    @Autowired
    Person person;

    @Test
    void test(){
        System.err.println(person);
    }
}

Print run to the console, it found that the automatic assembly can take effect.
Here Insert Picture Description
We then also registered in the configuration of a Person class components, assign the name attribute as "John Doe", age 40 attribute to show the difference.

package com.example.demo.annotation;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value = "com.example.demo.annotation")
public class MainConfig {

    @Bean
    public Person person111(){
        return new Person("李四",40);
    }

}

Such containers have two different types of components, and an id for the class name first letter lowercase person, other methods for the bean name person111.
Here is a look at unit testing is not?

@Test
void contextLoads() {
    AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfig.class);
    //按Person类型获取组件
    String[] typeNames=applicationContext.getBeanNamesForType(Person.class);
    for (String typeName:typeNames) {
        System.err.println(typeName);
    }
}

Print run out to see the results:
Here Insert Picture Description
you can see now there are two IOC containers Person type components.

Again run the unit tests and see the results:
Here Insert Picture Description
you can see that although there are now two types of components Person containers, but the default is the id of the assembly of components person.
So in order to assemble a component person111 id of how to do it?

Second, a plurality of automatic assembly of components of the same type

1, @Primary comment

Add annotations directly @Primary registered location bean components

@Bean
@Primary
public Person person111(){
    return new Person("李四",40);
}

Run the test unit, the print results are as follows:
Here Insert Picture Description
found from the results, the marked @Primary bean components are preferentially assembled.

2, modify the assembly name

Commented just added @Primary notes, change the name of automatic assembly attributes:

@Autowired
Person person111;

And then modify the unit test run

@Test
void test(){
    System.err.println(person111);
}

Operating results found now in force is the id of the component person111:
Here Insert Picture Description

3, using @Qualifier comment

With @Qualifier directly specifying annotation component id attribute value to be assembled. Now assembling component id is specified person.

@Autowired
@Qualifier(value = "person")
Person person111;

Unit tests run again and found that for the person id and assembled components:
Here Insert Picture Description
Apart @Autowired annotation, @ Resource, @ Inject annotation may also be used for automatic assembly.
But @Resource is not powerful enough, @ Inject need to import additional packages, in the Spring framework, our first choice is still @Autowired.
In addition @Resource and @Inject still be able to normal use after leaving the Spring framework, @Autowired currently only take effect in the Spring framework.

Three, @ Profile automatic assembly according to the environment

Sometimes we need different according to different environments registration component, assuming that there are dev develop, test and prod produce three test environment.
To realize how different assembly components of different environments it? @Profile annotations can help you do so.
Configuration class, multi-class configuration to register several bean:

package com.example.demo.annotation;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {

    @Bean
    public Person person111(){
        return new Person("李四",40);
    }

    @Bean
    public Person person222(){
        return new Person("张三",30);
    }

    @Bean
    public Person person333(){
        return new Person("王五",50);
    }
}

Test unit:

package com.example.demo;

import com.example.demo.annotation.MainConfig;
import com.example.demo.annotation.Person;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
class annotationTest {
    
    @Test
    void contextLoads() {
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfig.class);
        String[] typeNames=applicationContext.getBeanNamesForType(Person.class);
        for (String typeName:typeNames) {
            System.err.println(typeName);
        }
    }

}

IOC container unit test run to see these components
Here Insert Picture Description
bean components really are just registered. Now they are marked to @Profile notes, and are set to prod, test, dev environment.

@Profile("prod")
@Bean
public Person person111(){
    return new Person("李四",40);
}

@Profile("test")
@Bean
public Person person222(){
    return new Person("张三",30);
}

@Profile("dev")
@Bean
public Person person333(){
    return new Person("王五",50);
}

Running unit tests, found that IOC container in a Person component gone
modify the unit test sets up the environment to prod and test (can develop a variety of environment at the same time).

@Test
void contextLoads() {
    AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
    applicationContext.getEnvironment().setActiveProfiles("prod","test");
    applicationContext.register(MainConfig.class);
    applicationContext.refresh();

    String[] typeNames=applicationContext.getBeanNamesForType(Person.class);
    for (String typeName:typeNames) {
        System.err.println(typeName);
    }
}

Unit tests run again, to find that the test prod and the components are introduced into the vessel IOC.
Here Insert Picture Description
To delete the following components of the @Profile dev notes, unit tests run again:
Here Insert Picture Description
found no marked @Profile annotation bean default is to be introduced into the container.
Also this annotation can be marked on the class, the following label @Profile annotation on the class configuration and set test environment.

package com.example.demo.annotation;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Profile("test")
@Configuration
public class MainConfig {

    @Bean
    public Person person111(){
        return new Person("李四",40);
    }

    @Bean
    public Person person222(){
        return new Person("张三",30);
    }

    @Bean
    public Person person333(){
        return new Person("王五",50);
    }
}

This means that only in a test environment, the bean will be imported into the IOC container.
Testing means, arranged to activate the environment test:

@Test
void contextLoads() {
    AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
    applicationContext.getEnvironment().setActiveProfiles("test");
    applicationContext.register(MainConfig.class);
    applicationContext.refresh();
    String[] typeNames=applicationContext.getBeanNamesForType(Person.class);
    for (String typeName:typeNames) {
        System.err.println(typeName);
    }
}

Results expected:
Here Insert Picture Description
since the current environment is test, all the classes so arranged bean components are introduced into the vessel IOC.

Published 17 original articles · won praise 1 · views 301

Guess you like

Origin blog.csdn.net/weixin_43424932/article/details/104081211