Get the App
SLTechnology News&Howtos  ›  Development  › 

How to customize the externalization extension mechanism in Spring Cloud

Shulou Source: shulou.com Published: 2022-06-01 12:06:18 09月20日 Update

This article mainly explains "how to customize the externalization extension mechanism in Spring Cloud". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn how to customize the externalization extension mechanism in Spring Cloud.

Spring Cloud has enhanced the attribute source function of Environment.

In the spring-cloud-contenxt package, the PropertySourceLocator interface is provided to implement the extension of property file loading. We can extend our externalized configuration loading through this interface. The definition of this interface is as follows

Public interface PropertySourceLocator {/ * * @ param environment The current Environment. * @ return A PropertySource, or null if there is none. * @ throws IllegalStateException if there is a fail-fast condition. * / PropertySource locate (Environment environment);}

The abstract method locate needs to return a PropertySource object.

This PropertySource is the attribute source stored in Environment. That is, if we want to implement custom externalization configuration loading, we just need to implement this interface and return PropertySource.

Following this line of thinking, we follow the following steps to implement the custom loading of the externalized configuration.

Custom PropertySource

Since PropertySourceLocator needs to return a PropertySource, we must define our own PropertySource to get the configuration source from the outside.

GpDefineMapPropertySource represents a class that takes the Map result as the source of the attribute.

Public class GpDefineMapPropertySource extends MapPropertySource {/ * * Create a new {@ code MapPropertySource} with the given name and {@ code Map}. * * @ param name the associated name * @ param source the Map source (without {@ code null} values in order to get * consistent {@ link # getProperty} and {@ link # containsProperty} behavior) * / public GpDefineMapPropertySource (String name, Map source) {super (name, source);} @ Override public Object getProperty (String name) {return super.getProperty (name) Public String [] getPropertyNames () {return super.getPropertyNames ();} extend PropertySourceLocator

Extend PropertySourceLocator and override locate to provide attribute sources.

The attribute source is loaded and saved from the gupao.json file to the custom attribute source GpDefineMapPropertySource.

Public class GpJsonPropertySourceLocator implements PropertySourceLocator {/ / json data source private final static String DEFAULT_LOCATION= "classpath:gupao.json"; / / Resource loader private final ResourceLoader resourceLoader=new DefaultResourceLoader (getClass (). GetClassLoader ()); @ Override public PropertySource locate (Environment environment) {/ / set property source GpDefineMapPropertySource jsonPropertySource=new GpDefineMapPropertySource ("gpJsonConfig", mapPropertySource ()); return jsonPropertySource } private Map mapPropertySource () {Resource resource=this.resourceLoader.getResource (DEFAULT_LOCATION); if (resource==null) {return null;} Map result=new HashMap (); JsonParser parser= JsonParserFactory.getJsonParser (); Map fileMap=parser.parseMap (readFile (resource)); processNestMap (", result,fileMap); return result / / load the file and parse private String readFile (Resource resource) {FileInputStream fileInputStream=null; try {fileInputStream=new FileInputStream (resource.getFile ()); byte [] readByte=new byte [(int) resource.getFile (). Length ()]; fileInputStream.read (readByte); return new String (readByte, "UTF-8");} catch (IOException e) {e.printStackTrace () } finally {if (fileInputStreamstreams saved null) {try {fileInputStream.close ();} catch (IOException e) {e.printStackTrace ();}} return null; / / parses the complete url saved to the result collection. To implement @ Value injection private void processNestMap (String prefix,Map result,Map fileMap) {if (prefix.length () > 0) {prefix+= ".; for (Map.Entry entrySet: fileMap.entrySet ()) {if (entrySet.getValue () instanceof Map) {processNestMap (prefix+ entrySet.getKey (), result, (Map) entrySet.getValue ()) } else {result.put (prefix + entrySet.getKey (), entrySet.getValue ());} Spring.factories

In the / META-INF/spring.factories file, add the following spi extension so that Spring Cloud scans it when it starts to load GpJsonPropertySourceLocator.

Org.springframework.cloud.bootstrap.BootstrapConfiguration=\ com.gupaoedu.env.GpJsonPropertySourceLocator wrote the controller test @ RestControllerpublic class ConfigController {@ Value ("${custom.property.message}") private String name; @ GetMapping ("/") public String get () {String msg=String.format ("configuration value:% s", name); return msg;}} periodic summary

Through the above case, we can find that the extension of custom configuration source can be easily realized based on the PropertySourceLocator extension mechanism provided by Spring Boot.

As a result, two questions are raised.

Where was the PropertySourceLocator triggered?

Now that the data source can be loaded from gupao.json, can it be loaded from a remote server?

PropertySourceLocator loading principle

Let's first explore the first question, the implementation process of PropertySourceLocator.

SpringApplication.run

When the spring boot project starts, there is a prepareContext method that calls back all instances that implement ApplicationContextInitializer to do some initialization work.

ApplicationContextInitializer is the original thing of the Spring framework, and its main function is to allow us to further set up and process the instance of ConfiurableApplicationContext before the ApplicationContext of the ConfigurableApplicationContext type (or subtype) does the refresh.

It can be used in web applications that require programmatic initialization of the application context, such as registering propertySource based on the context, or configuration files. And the requirements of this configuration center of Config just need such a mechanism to complete.

Public ConfigurableApplicationContext run (String... Args) {/ / omit the code. PrepareContext (context, environment, listeners, applicationArguments, printedBanner); / / omit the code return context;} PropertySourceBootstrapConfiguration.initialize

Among them, PropertySourceBootstrapConfiguration implements the ApplicationContextInitializer,initialize method code as follows.

@ Overridepublic void initialize (ConfigurableApplicationContext applicationContext) {List > source = locator.locateCollection (environment); if (source = = null | | source.size () = = 0) {/ / if source is empty, go directly to the next loop continue;} / / traverse source, and wrap PropertySource as BootstrapPropertySource and add it to sourceList. List

Tags: Configuration properties mechanisms up and down context files interfaces methods code instances that is applications sources environments programs types processes applications content situations Apple Docker Huawei Linux macOS MariaDB Microsoft MySQL NVidia OPPO Reno Huawei Apple Shulou Technology vpn Xiaomi