Make writing a habit together! This is the 7th day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details

  • Spring Reading Directory

Accumulate over a long period, constant dripping wears away a stone 😄

preface

In Spring Boot, the default loaded configuration file name is application.properties or application.yml. The values of the properties file are loaded into Spring’s Environment. You can use @Value and @ConfigurationProperties.

Application. Properties, Application. Yml we can call them master profiles, but in real development, it is impossible to put all the configuration in the master profile, and over time, the master profile will become larger and harder to maintain. Properties (yML), redis. Properties (wx.properties).

Unfortunately, our custom configuration file is not automatically loaded, we need to use the @propertysource annotation provided by Spring to load the specified configuration file.

Rely on

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> < version > 2.2.1. RELEASE < / version > < / dependency >Copy the code

Not using annotations

The configuration file

Application. Properties and juejin. Properties.

  • application.properties
blog.name = cxyxj
Copy the code
  • juejin.properties
juejin.home = https://juejin.cn/user/2164257578290398
Copy the code

test

@SpringBootApplication(scanBasePackages = "com.cxyxj.propertysource")
public class AppMain {

    public static void main(String[] args) {
        ConfigurableApplicationContext application = SpringApplication.run(AppMain.class);
        // Get the container's Environment
        Environment env = application.getEnvironment();
        // Obtain by key
        String blog = env.getProperty("blog.name");
        String juejin = env.getProperty("juejin.home"); System.out.println(blog); System.out.println(juejin); }} Result: cxyxjnull
Copy the code

See that juejin. Home is not loaded into the Environment object.

Use annotations to load specified properties

  • Start the class with the above comment and specify the configuration file address
@PropertySource("juejin.properties")
Copy the code
  • Start the result
cxyxj
https://juejin.cn/user/2164257578290398
Copy the code

PropertySource Annotation definition

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {
    String name(a) default "";

    String[] value();

    boolean ignoreResourceNotFound(a) default false;

    String encoding(a) default "";

    Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}
Copy the code

There are four annotations on the PropertySource class. @Target, @Retention, and @Documented are meta-annotations. Another one is @repeatable, what does it do? If we want an annotation to be Repeatable on a class, we can put @REPEATable on the annotation. The effect is as follows:

Next, look at the attributes in the annotations.

  • Name: Specifies the name of the source for this attribute. If omitted, a name is generated based on the property source.

    • Value: resource location of the properties file to load. supportpropertiesXMLProperty file format, for example:classpath:/cn/cxyxj/xx.propertiesorfile:/path/xxx.xml.Note: resource location wildcards (e.g. **/*.properties) are not allowed;
  • IgnoreResourceNotFound: Whether an error should be ignored if the specified properties file does not exist. The default is false, meaning that the properties file does not exist, and an exception is thrown. This property is new to Spring4.0.

  • Encoding: Specifies the encoding format of the resource file. If this parameter is not specified, the file’s default encoding format will be used. This property is new in Spring4.3.

  • Factory: specify custom PropertySourceFactory, use DefaultPropertySourceFactory by default.

Loads the specified XML file

  • Let’s create a name calledjuejin.xmlXML file with the following contents:

      
<! DOCTYPEproperties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <entry key="juejin.home">https://juejin.cn/user/2164257578290398</entry>
</properties>
Copy the code
  • @PropertySourceThe note is revised as follows:
@PropertySource(name = "juejin", value = {"juejin.xml"})
Copy the code
  • Start the result
cxyxj
https://juejin.cn/user/2164257578290398
Copy the code

Load the yml

As mentioned above, @propertysource only supports properties and XML properties file formats, which is definitely not possible, as YML is becoming more and more popular. So how do you get @propertysource to support YML files? To do this, use the Factory property and specify PropertySourceFactory.

  • Create ajuejin.ymlThe file
juejin:
  home: https://juejin.cn/user/2164257578290398
Copy the code
  • createYmlPropertyResourceFactoryClass and implementPropertySourceFactory, the rewritecreatePropertySourceMethods.
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

/ * * *@PropertySourceAnnotate the factory attribute specifies YmlPropertyResourceFactory class, yml can support read *@author: cxyxj
 * @create: the 2022-01-21 and * /
public class YmlPropertyResourceFactory implements PropertySourceFactory {

    private static String YML = ".yml";
    private static String YAML = ".yaml";
    / * * * *@paramName:@PropertySourceAnnotate the value of name *@paramResource: resource */
    @Override
    publicPropertySource<? > createPropertySource(String name, EncodedResource resource)throws IOException {
        // File name
        String filename = resource.getResource().getFilename();
        // The name of the attribute source
        String resourceName = Optional.ofNullable(name).orElse(filename);
        if(filename.endsWith(YML) || filename.endsWith(YAML)) { List<PropertySource<? >> yamlSources =new YamlPropertySourceLoader().load(resourceName, resource.getResource());
            return yamlSources.get(0);
        } else {
            // Other file suffixes
            return newDefaultPropertySourceFactory().createPropertySource(name, resource); }}}Copy the code
  • Modify the@PropertySource
@PropertySource(name = "juejin", value = {"juejin.yml"},factory = YmlPropertyResourceFactory.class)
Copy the code
  • Start the effect
cxyxj
https://juejin.cn/user/2164257578290398
Copy the code

  • If you have any questions or errors in this article, please feel free to comment. If you find this article helpful, please like it and follow it.