Spring Boot Auto Configuration(The Magic explained #theory)
Spring boot is taught under the umbrella of titles of “fast programming” and “auto configuration”. If you check the definition of spring boot, you’d likely to see that the simple formula below.
spring boot = spring core + auto configuration
although there’re many advantages of spring boot, i’d summarize it like spring core with auto configurations.
If you’re a developer who either use spring core or not you must have encountered situations where e.g you need to go to a database.
In such circumstances you would simply configure the third party connection tools on your project.-at this point to more concrete the explanation, i will continue with actual configurations of mybatis-
If you have mybatis -third party tool allows you to connect a database in your java application- you’ll need to configure it as shown below to connect to the database and to execute your custom sql queries
After doing this configurations you can start using mybatis easily. But wait! this was just only one of the configurations you have to do, if you’re using spring mvc for example then you should do its configurations as well, which believe me, it’s more complicated than that one.
Over time you’ll see that configuring for each dependency is, with simple terms, time consuming.
We want to start to develop our program as soon as possible without concerning about configurations and the complexity right? so what is the solution to this? how we could address this issue, wouldn’t be great that if the 3rd party library providers do the all necessary configurations according to our parameters that we’ll supply and we simply call the basic classes and methods to start using?
Let’s get back the previous example of mybatis and figure out how we can auto configure.
If you probe the configuration.xml file you’ll see that some variables are hardcoded like url, username, password, database provider and also there’re some mybatis specific values such as cacheEnabled etc. which is also hardcoded.
First thing we should do is to de-couple these values and enable, the library user, to define it’s specific values. With the other words, we should read these values from a properties file.
Properties File : In spring project, there’re some files called xyz.properties, the most known is application.properties file.
You can simply put any key-value pairs to these files with key = value syntax and use them later on any where on your code.
Here a section of my application.properties file.
spring.datasource.url=jdbc:mysql://localhost:3306/airportdb
spring.datasource.username=username
spring.datasource.password=passoword
spring.datasource.driver-class-name =com.mysql.jdbc.Driver
mybatis.configuration.map-underscore-to-camel-case = true
mybatis.configuration.defaultStatementTimeout = 10
as it stands for itself, i simply provided my database address with user and password, and the driver i use accompany with 2 mybatis specific configuration values. By typing these key-values down, i provide everything to the 3rd party library to configure itself.
Assumption Based Configuration
In the previous chapter we checked out the auto configuration from the perspective of consumer-developers, but this time assume you’re a developer who’ll develop a public library for the other spring developers to use, how would you handle the auto configuration?
As i’ve just mentioned that there’s a file in spring which stores key-value pairs called <xyz>.properties. Instead of hard coding the some configuration values into our library, you would assume that the 3rd party user will provide these configuration values in its configuration file, so we simply develop our library in a way that reads the necessary values from <xyz>.properties file.
At this point, we simply create our beans by reading the values from <xyz>.properties file. In next article, our demo application, i’ll use @ConfigurationProperties annotation to achieve this but you can check the other ways of doing this here.
Autoscaning of 3rd Party jars
When i was studying spring core and boot i saw that there’re many ways of registering a spring bean to your application context. One of these methods is done by component scanning.
In this technique you simply define @ComponentScan annotation somewhere in your base package of your application and the spring scans all the sub-packages and files defined inside those packages and looks for any classes defined with annotation of either @Configuration or @Component and its derivatives and automatically import them to the application context. So in any spring boot application you can simply come accross something like that below
if you go inside the @SpringBootApplication annotation
You can see that, what we called @SpringBootApplication is actually a combined annotation of a few other annotations. I’d like to emphasize the annotation called @ComponentScan here. This is where the component scanning begins.
Okay but what about the beans defined in 3rd party jars?
if you check the maven dependencies of your application, you’ll see there’re many jar files that holds many spring beans ready to use, and you can use these beans in your applications with no effort.
But we didn’t register or scan these beans, how did they register themselves?
Spring.factories
Another way of registering a bean to you application context and is not taught commonly is; using a file called spring.factories
Besides the componentScanning and xml based configuration techniques you can also register your beans to your application context with that file.
When spring application starts up, spring will look for a file inside your resources/META-INF called spring.resources and import the beans defined in that file to your application context in addition to component scanning and other bean registration methods.
What makes this method — file special is, spring does that not only for your application but also all of your 3rd party libraries, another words, spring goes through each jar file and look for resources/META-INF/spring.factories file and read the instructions there and register beans to your application context thus you are able to import beans defined 3rd party libraries to your application and use them.
So if we check out any xyz-autoconfiguration.jar file above we must expect to find that file
and we yield it, as you can see in that file there’re some bean paths. Thus our application context is able to import all the beans defined in those factories files of 3rd party jars.
To Sum Up
When you write a library with spring for other developers
- Do your auto configuration assuming that all the key-value configuration properties are defined in the <xyz>.config file and try to read that file
(you can see how to do that here) - To inform the spring mechanism of the library user, supply your bean packages into your resources/META-INF/spring.factories file. Thus when the user imports your jar file its application context will aware of your beans.
I know there’s a lot to digest here but once you’re ready, we’ll be implementing all the theory here to a simple application.
till then take care of .