Summary
This article focuses on how to encapsulate a spring project (especially some public tool class projects), based on the idea of Spring boot's automatic configuration, so that other spring-boot projects can be quickly configured after introduction.
Autoconfiguration
An important feature of Spring-boot is that it offers a wide variety of autoconfiguration. such as Datasourceautoconfiguration. This way we only need to configure the configuration file as follows
spring: datasource: url: jdbc:mysql://xxxxxxxxxxx/realname username: xxxxx password: xxxxx driverClassName: com.mysql.jdbc.Driver
Spring-boot will inject a datasource in the container according to our configuration information. So how does spring boot know that datasourceautoconfiguration is an auto-config class? It's actually very simple:
- Spring boot will read all file classpath:\meta-inf\spring.factories files at boot time, Spring.factories is actually a properties file, that is, key = The form of value.
- Gets the value of the Key=org.springframework.boot.autoconfigure.enableautoconfiguration configuration item in Spring.factories (the full path of the class) as the Spring boot configuration class
Spring Boot This concept of "convention over configuration" can greatly simplify the writing of configuration code. So, we can follow the above routines to write a Spring-boot automatic configuration class bar
Actual combat
There is now a configuration bean--printafterinitbean that requires the spring container to be started, print a message once, and the content of the message is defined in the configuration file
The first step is to write the configuration Bean--printafterinitbean
The code is as follows, because it is just a simple example where the configuration bean can actually be any other complex configuration bean, such as DataSource. Often a common package requires more than one such configuration bean to complete its configuration.
public class PrintAfterInitBean implements InitializingBean { private String message; public void afterPropertiesSet() throws Exception { System.out.println(message); } //setter getter}
The second step is to create a autoconfiguration.
If you search for the classes under Spring boot, you will find that there are actually a lot of names like xxxautoconfiguration classes, which are some of the shortcut configuration classes that spirng boot has made for us. Create a testautoconfig, as an automatic configuration class
@Configurationpublic class testautoconfig { @Bean @ Configurationproperties (prefix = "init") @ Conditionalonmissingbean (printafterinitbean.class) @ConditionalOnProperty (prefix = "init", value = "message") public printafterinitbean printafterinitbean () {return New printafterinitbean ();}
- @ConfigurationProperties is a handy annotation for attribute injection provided by spring boot, which is actually similar to @value
- @ConditionalOnMissingBean means that a bean with no printafterinitbean type in Beanfactory will be created, otherwise it will be ignored. This is the so-called "Meet automatic Configuration Conditions", in the same way, conditionalonproperty means that when there is configuration prefix init, configuration value is the configuration of the message, it will take effect. The annotations in the @ConditionalOnXXX series are for automatic configuration, without intrusion into the user's configuration.
Step three, create the Spring.factories
Create a meta-inf/spring.factories under resources, and then configure the class for the second step in the file
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.netease.xxx.xxx.UrsPropertyAutoConfig
This completes a spring boot automatic configuration, and if there is a init.message configuration, then spring boot will print the Init.message configuration corresponding value.
Summary
Spring Boot's automatic configuration provides a simple set of deployment options for writing a duplicate configuration code (or XML file), so it's easy to pull when the other spring boot projects rely on our jar. As you can see from the code, Spring Boot does not actually have any substantial innovation, but simply transforms some of the "agreed" configuration information into a configuration that was originally implemented through code or XML.
Common Annotations @conditionalonxxx
As already mentioned, the @ConditionalOnXXX series is mainly about whether the automatic configuration takes effect, such as conditionalonclass, which takes effect if a class exists. This series of annotations knows the usage by name and therefore does not introduce too much. @ConditionalOnXXX can be used on class names and method names.
- Used on the class name, to be used with @Configuration, determines whether the configuration class is in effect
- For the method name (note: If the method is also a configuration class, that is, with @configuration annotations), used in conjunction with @bean, to determine whether the @bean generated
Use the Datasourceautoconfiguration code to illustrate,
@ConfigurationNote: This configuration path takes effect when there are datasource.class and Embeddeddatabasetype.class present@ConditionalOnClass ({datasource.class, embeddeddatabasetype.class})@EnableConfigurationProperties (Datasourceproperties.class)@Import ({registrar.class, datasourcepoolmetadataprovidersconfiguration.class})Publicclass datasourceautoconfiguration { private static final Log logger = Logfactory. GetLog (Datasourceautoconfiguration.class); @Bean // Note: The public datasourceinitializer Datasourceinitializerreturn New datasourceinitializer (properties, ApplicationContext);} ...}
The core idea of automatic configuration is not to encroach on the user's code, similar to "you have to use your, you do not have me to help you do the default settings." Therefore, we need to pay attention to this when we develop an automatic configuration class, otherwise it's a bit of a bully clause.
@EnableConfigurationProperties
In general, our automatic configuration classes rely on external configuration information, and these external configuration information can be encapsulated as a class, similar to the @enableconfigurationproperties in datasourceautoconfiguration above ( Datasourceproperties.class), the Datasourceproperties class is used to save datasource-related configuration information. The idea that "convention is better than configuration" is reflected here, If the configuration information is prefixed with Spring.datasource, then the configuration information is injected into the Datasourceproperties class for datasourceautoconfiguration use.
@ConfigurationProperties(prefix = "spring.datasource")public class DataSourceProperties implements BeanClassLoaderAware, EnvironmentAware, InitializingBean { ... private Class<? extends DataSource> type; private String driverClassName; private String url; private String username; private String password; ...
@AutoConfigureAfter
In some special cases, some auto-configuration classes need to be done after some other configuration class, such as relying on another automatically configured Bean, which is @autoconfigureafter to be constrained at this time.
@Import
@Import is also a common configuration annotation, mainly used to introduce other configuration classes, but another useful configuration is to introduce a Importbeandefinitionregistrar interface, This is used to register some beandefinition at the time of the ApplicationContext initialization phase. Of course, common beans can be injected through @bean annotations, but some of the beans used by spring ApplicationContext during startup are not good, such as Beanpostprocessor, Beanfactorypostprocessor.
Summarize
Spring Boot Core idea is "contract better than configuration" idea, when creating a micro-service has many unique advantages, often only in a few lines of configuration, you can deploy an application. This is more of a business dimension in coding. And if we write a public package can be done in just a few lines of configuration, not only the code level of the reduction, but also the access is a "one-stop service" experience. Of course, the premise is that the access party is also using spring Boot.
How to write Spring-boot automatic configuration