Springboot custom configuration Boolean property cannot take effect
The attribute name cannot start with is, for example, the isLog attribute. No matter how you set the value of this attribute in the configuration file, it will not take effect. Just change it to log.
The version I use
<parent> <groupId></groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.</version> <relativePath/> </parent>
Springboot automatic configuration principle
Springboot automatic configuration
1. Overview
The function of automatic configuration is the key technology for simplifying application. The idea is that agreement is greater than configuration, which means that an engineering agreement must have transaction functions, AOP functions, MVC functions, etc. Therefore, when springboot creates a project, it automatically instantiates the classes required by these functions and adds them to the spring container. This is that agreement is greater than configuration, and it is agreed that these functions must be present.
2. SPI mechanism in springboot
Java native SPI is a service provider interface.
It automatically loads the defined classes in the file by looking for files in the META-INF/services folder under the ClassPath path.
This mechanism provides possibilities for many framework extensions, such as SPI is used in Dubbo and JDBC.
- 2.1. SPI mechanism in JDK
public interface Log { boolean support(String type); void info(); }
Create a file in the resources/META-INF/services directory. The file name must be the same as the fully qualified name of the interface.
This interface file is configured with the full qualified names of all implementation classes of the interface.
Then jdk api loads the configuration file
//jdk api loads configuration file configuration instance ServiceLoader<Log> all = ();
- 2.2. SPI mechanism in springboot
The specific process is similar to the above. Create a META-INF folder under the resources of the project, create a file under the folder, and the file configuration content is as follows:
=\ .Log4j,\ ,\ .Slf4j
The configured key is the complete qualified name of the interface, and the value is the various implementation classes of the interface, separated by the "," number.
The loadFactoryNames method obtains the names of all classes that implement the interface.
@Test public void test() { List<String> strings = SpringFactoriesLoader .loadFactoryNames(, ()); for (String string : strings) { (string); } }
The loadFactories method obtains instances of all classes that implement the interface.
@Test public void test1() { List<String> strings = SpringFactoriesLoader .loadFactories(, ()); for (String string : strings) { (string); } }
- 2.3. We use (, ()); method call as an example to analyze its source code
You can see that springboot spi loads the entire project jar package and its own project definition files.
Its core code
Properties properties = (resource);
public static Properties loadProperties(Resource resource) throws IOException { Properties props = new Properties(); //Core code, wrap the file into properties object fillProperties(props, resource); return props; }
The SPI in springboot actually loads the files in the entire project, and then builds a mapping relationship between key and value by the contents in the file. However, this mapping relationship is a mapping relationship between type and list.
3、@EnableAutoConfiguration
The @EnableAutoConfiguration annotation is the core annotation for automatic configuration of springboot. This is because of this annotation, such as transactions, caches, aop, mvc, etc., will automatically import functions such as springboot projects. The various names provided by the Spring framework are Annotation definitions starting with @Enable, such as @EnableScheduling, @EnableMBeanExport, etc. The concept and way of doing things are actually in line with each other. To summarize it simply, with the help of @Import's support, collect and register bean definitions related to specific scenarios.
@SuppressWarnings("deprecation") @Target() @Retention() @Documented @Inherited @AutoConfigurationPackage @Import() public @interface EnableAutoConfiguration { ... }
@Import a class, this AutoConfigurationImportSelector automatically configures the class
- 3.1、DeferredImportSelector
DeferredImportSelector This interface is a subinterface of the ImportSelector interface, so how is it used?
// public class DeferredImportSelectorDemo implements DeferredImportSelector{ @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { ("====="); return newString[]{()}; } //Return a class that implements the Group interface@Override public Class<?extendsGroup> getImportGroup(){ return ; } private static class DeferredImportSelectorGroupDemo implements Group{ List<Entry> list=new ArrayList<>(); //Collect classes that need to be instantiated@Override public void process(AnnotationMetadata metadata,DeferredImportSelector selector){ ("====="); String[] strings=(metadata); for(String string:strings){ (newEntry(metadata,string)); } } //Return the collected class to the spring container@Override public Iterable<Entry> selectImports(){ ("====="); return list; } } } //The bean to be instancedpublic class DeferredBean{}
This class must be imported from @Import
@Component //Although Import is an instantiation of a class, the class that Import comes in can implement some interfaces @Import({})public class ImportBean{}
This implements instantiation of a class.
- 3.2、EnableAutoConfigurationImportSelector
The AutoConfigurationImportSelector class, this class is the class that comes in @Import in the @EnableAutoConfiguration annotation. You can see that this class implements the DeferredImportSelector interface.
This class is actually collecting all classes in the file with the @EnableAutoConfiguration type as key, and then handing these classes to spring for instantiation. These classes are the support classes for aop, transaction, cache, mvc and other functions we call. This is the loading principle of automatic configuration.
4、@Configuration
It is the @Configuration used by the configuration class of the Spring Ioc container in JavaConfig form. The SpringBoot community recommends using the configuration form based on JavaConfig. Therefore, after the startup class here is marked with @Configuration, it is actually an IoC container configuration class.
The return value of the @Bean method will be registered as a bean definition to Spring's IoC container, and the method name will default to the id defined by the bean.
5、@ComponentScan
In fact, it automatically scans and loads components that meet the conditions (such as @Component and @Repository, etc.) or bean definitions, and finally loads these bean definitions into the IoC container.
You can use basePackages and other properties to customize the range of @ComponentScan automatically scan. If not specified, the default Spring framework implementation will scan from the package that declares @ComponentScan class.
Customize SpringBoot Starter
1. Introduce the configuration dependencies of the project
<dependency> <groupId></groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>2.1.</version> </dependency>
2. Create xxxService class
Complete relevant operation logic
@Data public class DemoService{ private String str1; private String str2; }
3. Define the xxxProperties class
Attribute configuration class, completes the operations related to attribute configuration, such as setting attribute prefixes, used to configure in
//Specify that the prefix configured by the project in the property file is str, that is, you can change the value of the property class field str1 by str.str1=springboot in the property file.@SuppressWarnings("ConfigurationProperties") @ConfigurationProperties(prefix = "str") public class DemoProperties { public static final String DEFAULT_STR1 = "I know, you need me"; public static final String DEFAULT_STR2 = "but I also need you"; private String str1 = DEFAULT_STR1; private String str2 = DEFAULT_STR2; }
4. Define the xxxAutoConfiguration class
Automatic configuration class to complete bean creation and other tasks
// Define java configuration class@Configuration //Introduce DemoService@ConditionalOnClass({}) // Correlate the relevant attribute fields to this class one by one, and generate a bean@EnableConfigurationProperties() public class DemoAutoConfiguration { // Inject property class @Autowired private DemoProperties demoProperties; @Bean // Create this bean when the container does not have this bean @ConditionalOnMissingBean() public DemoService helloworldService() { DemoService demoService= new DemoService(); demoService.setStr1(demoProperties.getStr1()); demoService.setStr2(demoProperties.getStr2()); return demoService; } }
5. Create directory META-INF under resources
Create in the META-INF directory
When SpringBoot starts, the project's automated configuration class will be loaded based on this file.
=
6. Use custom Starter in other projects
<!--Introduce customizationStarter--> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-demo</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
7. Write attribute configuration file
#Configure custom attribute informationstr.str1=Why do I always have tears in my eyes str.str2=That's because I love you deeply
8. Write annotations to use
@RestController public class StringController { @Autowired private DemoService demoService; //Introduce DemoService in Custom Starter @RequestMapping("/") public String addString(){ return demoService.getStr1()+ demoService.getStr2(); } }
Summarize
The above is personal experience. I hope you can give you a reference and I hope you can support me more.