Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to customize the externalization extension mechanism in Spring Cloud

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

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

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report