SpringBoot: Operating principle Inquiry

SpringBoot: Operating principle Inquiry

pom.xml

Before we write HelloSpring, in the end is how to run it

We look at pom.xml file

Into the parent project, here is the real management SpringBoot all depend on which version of the application place, SpringBoot version control centers;

After we import dependence is no need to write the default version; however, if the imported package is not managed in dependence on the need to manually configure version;

Launcher

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

springboot-boot-starter: the scene is springboot starter

Here the spring-boot-starter-web assembly is introduced to help us web module is operating normally depends;

SpringBoot all the features scenes are extracted, made a number of starter (starter), you only need to introduce these starter in the project, will depend on all the relevant import in, we use the import feature is what kind of scene starter can;

 The main program

package com.kuang.springbootdemo02;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

//@SpringBootApplication 来标注一个主程序类 , 说明这是一个Spring Boot应用
@SpringBootApplication
public class SpringbootDemo02Application {

    public static void main(String[] args) {
        //将Spring应用启动起来
        SpringApplication.run(SpringbootDemo02Application.class, args);
    }

}

SpringBootApplication

@SpringBootApplication :SpringBoot应用标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;进入这个注解:

@SpringBootConfiguration ; SpringBoot的配置类 ;标注在某个类上 , 表示这是一个SpringBoot的配置类;我们继续进去这个注解查看

@Configuration:配置类上来标注这个注解 ,配置类-----配置文件;我们继续点进去,发现配置类也是容器中的一个组件。@Component

 

EnableAutoConfiguration

 我们回到 SpringBootApplication 注解中继续看。

@EnableAutoConfiguration :开启自动配置功能

以前我们需要配置的东西,SpringBoot可以自动帮我们配置 ; @EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

我们点击去查看

 

@AutoConfigurationPackage : 自动配置包 , 点进去看到一个 @Import({Registrar.class})

 

@import :Spring底层注解@import , 给容器中导入一个组件 ,导入的组件由 {Registrar.class} 将主配置类 【即@SpringBootApplication标注的类】的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;

然后回来继续看:@Import({AutoConfigurationImportSelector.class}) :给容器导入组件 ;

 AutoConfigurationImportSelector : 导入哪些组件的选择器 ;

它将所有需要导入的组件以全类名的方式返回 , 这些组件就会被添加到容器中 ;

它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;

有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;

//AutoConfigurationImportSelector中获取配置文件信息;
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
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;
}

SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguation.class,classLoader);

这里的getSpringFactoriesLoaderFactoryClass()方法返回的就是我们最开始看的启动自动导入配置文件的注解类;

 

进入 SpringFactoriesLoader 查看;

找到对应的方法:发现最终会去读取一个配置文件 : META-INF/Spring.factories 的文件 。 

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

    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 factoryClassName = ((String)entry.getKey()).trim();
                        String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                        int var10 = var9.length;

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

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

 

我们打开spring.factories的配置文件 , 看到了很多自动配置的文件;这就是自动配置根源所在!

SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;

以前我们需要自己配置的东西 , 自动配置类都帮我们解决了

整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;

 

 

Guess you like

Origin www.cnblogs.com/hellokuangshen/p/11256189.html