Spring Boot Autoconfiguration
By AmarSivas | | Updated : 2021-03-16 | Viewed : 8351 times

The current article helps you to understand of Spring Boot Auto Configuration mechanism with some simple examples. Here we will learn about internal mechanism of the Auto Configuration and its necessity.
Table of Contents:
Auto Configuration Necessity
Typically, the Spring application is required many configurations i.e., configurations that are required for Spring MVC Dispatcher Servlet, View resolvers, and other required jar classes. Please consider a SpringMVC application with Hibernate. Here below-shown configurations are required. Please look into those configurations to implement the Spring MVC Application.
Below provided configuration is for Web.xml where DispatcherServlet configured.
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Please find the below-given XML configuration for spring-dispatcher-servelet.xml
<context:component-scan base-package = "com.docsconsole.tutorials.springmvc.*" />
<bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value = "/WEB-INF/views/" />
<property name = "suffix" value = ".jsp" />
</bean>
If the application needs Hibernate Configurations then below-given configuration should be added.
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url" value="jdbc:mysql://localhost:3306/TestDB" />
<beans:property name="username" value="XXXXXXX" />
<beans:property name="password" value="XXXXXXX" />
</beans:bean>
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.docsconsole.springmvc.model.Author</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
So many configuraions are required for Spring MVC applciation. But if we use Spring Boot these are all configured automatically.
Auto Configuration
Spring Boot has brought up a new idea to automate the configuration part. Auto-Configuration in Spring Boot automatically configures all the dependencies for an application. Here Spring Boot will find classes in the classpath and start Auto Configuration. So beans will be registered here in Application Context for the instantiation with wiring up required beans. Here Bean registration will be done based on some conditions.
This powerful feature is very helpful for implementation and making the developer's life easy that it is not required configurations. And we can implement customized starters that would handle customized configuration automatically.
How Does AutoConfiguration Work?
The magic of autoconfiguration is with annotation called
Implementation of Auto Configuration
We will learn here the way of the working mechanism of Spring Boot's Auto Configuration. Before that, we will understand the
@Profile Annotation
Sometimes Spring beans registration is required based on the type of environment. Suppose in Dev the DB properties should point to Dev Database only whereas in Production these properties should be production Database.
So To achieve these we must separate all the properties as seperate file per the environment means each separate environment must have a separate config file. Spring has introduced to resolve this problem with @Profile.
@Configuration
public class AppConfig
{
@Bean
@Profile("DEV")
public DataSource devDataSource() {
}
}
By specifying the System Property
@Conditional Annotation
This is introduced in Spring to add additional flexibility to @Profile. Because @Profile will be used to enable/disable Spring beans registration based on the activated profile. But it is not sufficient to register the beans. It should be based on some conditions.
So registration can be done based on the following conditions.
-
Register a bean If a Class has existed in ClassPath.
-
Register a bean If a Class is not registered with ApplicationContext.
-
Register a bean If a Class file is located in some location.
-
Register a bean If a property value is configured in some configuration file.
-
Register a bean If a System property is absent/present.
Suppose consider OracleDataDAO implemented with DataDAO which is used for getting connenction from Oracle database. Once the connection happens then data will be fetched from the database. So OracleDataDAO class's registration is required. Here the condition for Registering of a bean is If a property value i.e.,
Please observe the below-given example code for OracleDataDAO.
public class OracleDataDAO implements DataDAO
{
@Override
public List getTableData() {
//
}
}
Based on passing the
The condition should be implemented as given below for the Oracle database. It will be implemented based on system
public class OracleDatabaseTypeCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata)
{
String enabledDBName = System.getProperty("DbType");
return (enabledDBType != null && enabledDBType.equalsIgnoreCase("Oracle"));
}
}
If the condition is the Type of loaded driver class of Oracle then the condition will be as given below.
public class OracleDriverTypeCondition implements Condition
{
@Override
public boolean matches(ConditionContext conditionContext,AnnotatedTypeMetadata metadata) {
try {
Class.forName("com.oracle.driver");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}
If we run the application like
In the same way as the above-written code, we can write with an annotation which will be very useful for users.
public class DatabaseTypeCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext,AnnotatedTypeMetadata metadata) {
Map<String, Object> attributes = metadata.getAnnotationAttributes(DatabaseType.class.getName());
String name = (String) attributes.get("value");
String enabledDBType = System.getProperty("dbType","Oracle");
return (enabledDBType != null && type!= null && enabledDBType.equalsIgnoreCase(type));
}
}
Now we can use the
@Configuration
@ComponentScan
public class AppConfig {
@DatabaseType("Oracle")
public DataDAO dataDAO(){
return new OracleDataDAO();
}
}
So here it will check the loaded driver class whether Oracle or not. If yes Spring will register the oracle driver class then appropriate DataDAO class will be used for fetching the data from the Oracle Database.
Auto Configuration Example
Generally, the Auto Configuration will try to find the classes which are available in the
@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {
}