Some simple knowledge points of SpringBoot (not difficult to pinch at all) The first issue of springboot series

words written in front

Because I was frustrated with the project, I came back and brushed springboot for the second time.
Please add image description

Because I am too forgetful, I will take a note and hope that the second brush will allow me to learn some new things
. The time left for me has already exceeded 8. I hope that I will not go to work in the electronics factory in the second half of this year.
insert image description here

Please add image description

@Configuration annotation

This annotation is to mark that this class belongs to springboot management
insert image description here
@Configuration(proxyBeanMethods = true)
If this parameter is true, the same object in the IOC container is used in it.
If it is flase, a new object is created every time it is used.

/**
 * 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
 * 2、配置类本身也是组件
 * 3、proxyBeanMethods:代理bean的方法
 *      Full(proxyBeanMethods = true)(保证每个@Bean方法被调用多少次返回的组件都是单实例的)(默认)
 *      Lite(proxyBeanMethods = false)(每个@Bean方法被调用多少次返回的组件都是新创建的)
 */
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
    
    

    /**
     * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
     * @return
     */
    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
    
    
        User zhangsan = new User("zhangsan", 18);
        //user组件依赖了Pet组件
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }

    @Bean("tom")
    public Pet tomcatPet(){
    
    
        return new Pet("tomcat");
    }
}

@Impot (used on classes) automatically creates imported components for the container

insert image description here
Inject with @Import
and then go to the container to see if you can find it
insert image description here

The result is that mypersion
insert image description here
can be found in the IOC container, which
is injected with Bean, and
the long one is injected through Import.

@Conditional conditional loading annotation

There are many annotations
insert image description here

This annotation means that if the IOC container does not have the object mypet, these beans will not be injected
insert image description here

@ImportResource import Spring configuration file

a configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans ...">

    <bean id="haha" class="com.lun.boot.bean.User">
        <property name="name" value="zhangsan"></property>
        <property name="age" value="18"></property>
    </bean>

    <bean id="hehe" class="com.lun.boot.bean.Pet">
        <property name="name" value="tomcat"></property>
    </bean>
</beans>

Use to directly load the bean into the ioc

@ImportResource("classpath:beans.xml")
public class MyConfig {
    
    
...
}

test

public static void main(String[] args) {
    
    
    //1、返回我们IOC容器
    ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

	boolean haha = run.containsBean("haha");
	boolean hehe = run.containsBean("hehe");
	System.out.println("haha:"+haha);//true
	System.out.println("hehe:"+hehe);//true
}

insert image description here
insert image description here

Inject the custom configuration of application.properties into the class

To inject, we must put what we want to inject into the springboot core configuration file

Use our own class: @Component+@ConfigurationProperties()

insert image description here
We need to inject the two data of mycar into car

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component  //把这个类放到容器中
@ConfigurationProperties(prefix="mycar") //读取配置文件中的mycar并把数值给赋给brand和price
public class Car {
    
    
    private String brand;
    private Integer price;

    @Override
    public String toString() {
    
    
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

When referencing a third-party package: @ConfigurationProperties()+@EnableConfigurationProperties

If we use a third-party library, we can't add @Component to the third-party library,
so we can add @EnableConfigurationProperties to the running class of springboot
insert image description here

insert image description here
insert image description here
let's visit
insert image description here

细嗦@SpringBootApplication

@SpringBootApplication is composed of the following three annotations

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
    
     @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication{
    
    }

@SpringBootConfiguration

insert image description here
This annotation is actually a @Configuration annotation
insert image description here
. This annotation is a sign that this class belongs to springboot management. This annotation has been said before.

Represents that the current class is a configuration class

@ComponentScan

means we want to scan those packages

@EnableAutoConfiguration(重点)

insert image description here
@EnableAutoConfiguration是

  1. @AutoConfigurationPackage

  2. Synthetic annotation for @Import({AutoConfigurationImportSelector.class})

@AutoConfigurationPackage

Automatic configuration package annotations make default package rules
insert image description here

It is actually an Import annotation (the role is to import a component into the container)
insert image description here

The role of this Registrar is to batch import a series of packages because the source code is too long.
Since it is a designated package to import, which package does it specify?
Of course, the answer is insert image description here
that this package is spicy
. This also explains a question why it is not started here. The package under the class cannot be scanned

@Import({AutoConfigurationImportSelector.class})

Using the Select mechanism to import in batches
, we enter this class and insert image description here
find this method

  public String[] selectImports(AnnotationMetadata annotationMetadata) {
    
    
        if (!this.isEnabled(annotationMetadata)) {
    
    
            return NO_IMPORTS;
        } else {
    
    
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

Now let's study this thing
insert image description here

autoConfigurationEntry.getConfigurations() batch import components into the container

When we enter this method, we can see that the configuration has undergone a series of operations,
such as taking out and removing the same operations, and finally we get the component we want to import into the container

 protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    
    
        if (!this.isEnabled(annotationMetadata)) {
    
    
            return EMPTY_ENTRY;
        } else {
    
    
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.getConfigurationClassFilter().filter(configurations);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }

This is to get all the configuration classes, we can break the point and take a look
insert image description here

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
           

insert image description here
Let's debug and this is the configuration we added

Let's enter the getCandidateConfigurations() method to see that it is configured by loading the factory

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    
    
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

Let's take a look at this factory class
insert image description here

 public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
    
    
        String factoryTypeName = factoryType.getName();
        return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    }

Let's go to return and see
insert image description here
that this loads all the configuration methods

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    
    
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
    
    
            return result;
        } else {
    
    
            try {
    
    
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                LinkedMultiValueMap result = new LinkedMultiValueMap();

                while(urls.hasMoreElements()) {
    
    
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();

                    while(var6.hasNext()) {
    
    
                        Entry<?, ?> entry = (Entry)var6.next();
                        String factoryTypeName = ((String)entry.getKey()).trim();
                        String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                        int var10 = var9.length;

                        for(int var11 = 0; var11 < var10; ++var11) {
    
    
                            String factoryImplementationName = var9[var11];
                            result.add(factoryTypeName, factoryImplementationName.trim());
                        }
                    }
                }

                cache.put(classLoader, result);
                return result;
            } catch (IOException var13) {
    
    
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
            }
        }
    }

Take a breakpoint

insert image description here
Look at this
insert image description here
insert image description here
. The location of our resource files is here. That is to say, all files in this location in
our current system and this package are scanned by default. This is the 127 configuration class files we loaded above. Springboot has been started to be loaded. 127 configuration classes These configuration classes cover almost all application scenarios of springbootinsert image description here

insert image description here

insert image description here



insert image description here

Let's see how many are
insert image description here
insert image description here
loaded in the startup class. We have loaded 127 plus we must have added more than 129, which means that some of them did not enter the container.

EnableAutoConfiguration : What have I done?

  1. Load components
  2. Read the configuration information from the configuration file and set it (referring to reading the configuration file below)
    insert image description here

Those 127 configurations will all be loaded but will be allocated on demand according to conditional assembly rules

Let's just go into one and have a look,
insert image description here
we can see this annotation
insert image description here

insert image description here
We mentioned earlier that this is a conditional annotation,
which means that this AOP will only be added to the container under the premise of importing the Advice package.

some notes

Add some annotations for components to the container

  • @Bean adds a normal component to the container
  • @Component represents a component
  • @Controller represents the controller
  • @Service represents business logic components
  • @Repository represents the database component
  • @Impot imports a lot of annotations for the container,
    some common annotations
  • @ComponentScan package scan annotation

To be continued…

The follow-up study notes are all in my spring boot column.
Click to enter the column .

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324144868&siteId=291194637