Understanding and automatic configuration of SpringBoot micro services

What is it microService

In comparison to a whole applications, micro-services can be a small module drawn from this large program in the past, and I extracted shaped like a user module in the electricity business project, the order module, why do it, such as an application has been deployed in multiple servers, and if you later need to modify the program, but also to modify the finish line on the re-operation on all servers, such a waste of human and material resources, but a program can be divided into multiple modules, a module, also known as a micro-services, a plurality of micro dynamic service deployment on multiple servers, if there is need to modify the function, simply specify the shelf micro services, other services are not affected micro; http interact with service between micro ; may correspond to a set of micro-services members of the development, developers can choose their own development language and database, also divided between the team clearer.

SpringBoot automatic configuration principle

Directly from the annotation @ main method of SpringBootApplication enter:

@SpringBootApplication
public class SpringbootConfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootConfigApplication.class, args);
    }
}

Point to go see @ EnableAutoConfiguration open automatically configure annotation:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)

Enter @ EnableAutoConfiguration :

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

See @ Import ({ AutoConfigurationImportSelector.class }) into which open the automatic configuration selector class, then point to see into AutoConfigurationImportSelector class has a selectImports () options, and introducing the assembly which depends method getAutoConfigurationEntry () method, the sixth line in the following code block:

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

Then enter getAutoConfigurationEntry () This method automatically obtain configuration entities:

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, 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.filter(configurations, autoConfigurationMetadata);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }

It can be seen that the sixth line has a code block getCandidateConfigurations () method of acquiring the candidate configuration, enter:

    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;
    }

This method has a Assert notEmpty, where it seems really determine whether this resource is empty, look at the back of the green word No classes found in the Configuration Auto META-INF / spring.factories , and META-INF / spring.factories file no automatic configuration class, can guess to be selected in the resource file is loaded inside; enter loadFactoryNames () method:

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

Here you can see a loadSpringFactories () method of loading seen before spring.factories file ends Factories, and then enter the method:

	private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
		MultiValueMap<String, String> result = cache.get(classLoader);
		if (result != null) {
			return result;
		}

		try {
			Enumeration<URL> urls = (classLoader != null ?
					classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
					ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
			result = new LinkedMultiValueMap<>();
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(url);
				Properties properties = PropertiesLoaderUtils.loadProperties(resource);
				for (Map.Entry<?, ?> entry : properties.entrySet()) {
					String factoryTypeName = ((String) entry.getKey()).trim();
					for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
						result.add(factoryTypeName, factoryImplementationName.trim());
					}
				}
			}
			cache.put(classLoader, result);
			return result;
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
	}

ClassLoader.getResources can see in the try (FACTORIES_RESOURCE_LOCATION):
ClassLoader.getSystemResources (FACTORIES_RESOURCE_LOCATION)); such a code, the class loader loads a resource from FACTORIES_RESOURCE_LOCATION:

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

SpringFactoriesLoader class has a position that is defined in the resource FACTORIES_RESOURCE_LOCATION META-INF / spring.factories this document, the document is automatically arranged in the springboot jar:
Here Insert Picture Description
each such class XXXAutoConfiguration are added to the last Spring container, Springboot automatic configuration is the above.

Published 12 original articles · won praise 3 · Views 247

Guess you like

Origin blog.csdn.net/qq_38599840/article/details/104138942