DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • How to Activate New User Accounts by Email
  • Why Camel K?
  • DDD and Spring Boot Multi-Module Maven Project
  • Spring Boot for Microservices: The New Age Framework for Your Apps

Trending

  • How To Validate Archives and Identify Invalid Documents in Java
  • The Convergence of Testing and Observability
  • Choosing the Appropriate AWS Load Balancer: ALB vs. NLB
  • Microservices With Apache Camel and Quarkus (Part 5)
  1. DZone
  2. Coding
  3. Frameworks
  4. Under The Boot – Spring Boot

Under The Boot – Spring Boot

How Spring boot is automatically creating right components for your app.

Dawid Kublik user avatar by
Dawid Kublik
·
Nov. 05, 15 · Tutorial
Like (17)
Save
Tweet
Share
23.91K Views

Join the DZone community and get the full member experience.

Join For Free

Remember the times when we had to register dispatchers, viewResolvers, etc. to make our spring application web app? Then there was @EnableWebMvc annotation, and now even this is redundant.

These days the only thing you need to do is to add org.springframework.boot:spring-boot-starter-web dependency to your project and everything else is done automagically.

The same goes for a database connection. Not that long ago the minimum DB-aware Spring-context configuration was:

  • Register data source (<jdbc:embedded-database id="dataSource" type="HSQL"/>)
  • Register entity manager (through entity manager factory) (<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">)
  • Register transaction manager (<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" >)
  • Rurn on annotation driven transaction boundaries (<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false"/>)

Along the way we dropped XML configs in favor of configurations. Now, all you need to do is to add another dependency org.springframework.boot:spring-boot-starter-data-jpa and some DB driver (like com.h2database:h2) and—again—Spring creates everything behind the curtains.

I don't know about you, but I grow suspicious when that many things happen without my knowledge. After using Spring Boot for a while I needed to look under the hood to feel safe again—not that much under—just enough to get back to my comfort zone.

High Level View

The basic mechanism goes like this:

All magically appearing beans are registered with Spring configurations (@Configuration).
But those are loaded only if specific conditions are met—namely:

  • The required class is available on the classpath (new beans magically created when dependency added).
  • The required bean was not created explicitly by a programmer.

So for example—to load WebMvcAutoConfiguration when Servlet, DispatcherServlet, and WebMvcConfigurerAdapter classes are on the classpath, then @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class }) is used.

This configuration loads all web MVC defaults, but again, for most of them only if the specific bean doesn't yet exist.

So, for example, to check if defaultViewResolver() should be created, @ConditionalOnMissingBean(InternalResourceViewResolver.class) is used.

@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
        WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
(...)
public class WebMvcAutoConfiguration {
    (...)

    @Bean
    @ConditionalOnMissingBean(InternalResourceViewResolver.class)
    public InternalResourceViewResolver defaultViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix(this.prefix);
        resolver.setSuffix(this.suffix);
        return resolver;
    }

    (...)
}

Where Is It Triggered?

It all begins with @SpringBootApplication, the one you annotate your main class with. If you check its source you'll find out @EnableAutoConfiguration there and this is responsible for most of the magic.

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(Application.class);
        application.run(args);
    }
}

If you check spring-boot-autoconfigure.jar/META-INF/spring.factories you'll find the org.springframework.boot.autoconfigure.EnableAutoConfiguration property which specifies which auto configurations will be used to "guess" and create beans you require.

Image title

DB Magic Example

So let's figure out how the required components for DB access are created.
To do so let's not use org.springframework.boot:spring-boot-starter-data-jpa dependency in our showcase, but start with org.springframework.boot:spring-boot-starter and see what dependencies should be added to create a database-aware app and how required steps are automagically performed.

With the spring-boot-starter:1.2.6.RELEASE dependency I got 22 beans registered by Spring in my app (18 Spring beans + 4 application specific beans). There is no dataSource or transactionManager amongst them.

I want to add a hibernate entity to the project so I will include the org.hibernate:hibernate-entitymanager compile dependency.
Now JtaAutoConfiguration with jta properties beans were added as javax.transaction.Transaction appeared on the classpath.
I was hoping for HibernateJpaAutoConfiguration to catch on, but this one also requires:

  • LocalContainerEntityManagerFactoryBean (to provide entityManager)
  • EnableTransactionManagement (to provide transactionManager)

Both can be found in org.springframework:spring-orm, so let's add this dependency to the classpath.

Now Spring will try to load HibernateJpaAutoConfiguration, but this one requires dataSource bean (@Autowired as a private field), and we are still missing it.

It's easy to figure out that dataSource will be created by DataSourceAutoConfiguration (found on list in spring.factories).

It seems that all conditions are met here, but the DataSourceAutoConfiguration class can't be classloaded yet as it uses org.apache.tomcat.jdbc.pool.DataSourceProxy, so it depends on org.apache.tomcat:tomcat-jdbc. Let's add it to the class path as well.

Running the app we can see that we're getting closer as this time hibernate.dialect can't be determined. No surprise here, it couldn't have been determined by Spring as we hadn't added any DB-specific dependency. So let's include com.h2database:h2a.

Everything seems to work now. 54 beans loaded by spring. Among them:

  • dataSource (org.apache.tomcat.jdbc.pool.DataSource—added by DataSourceAutoConfiguration.NonEmbeddedConfiguration.dataSource())
  • entityManagerFactory (org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean—added by JpaBaseConfiguration.entityManagerFactory() (parent of HibernateJpaAutoConfiguration))
  • transactionManager (org.springframework.orm.jpa.JpaTransactionManager—added by JpaBaseConfiguration.transactionManager() (parent of HibernateJpaAutoConfiguration)

Dependencies are summarized in the diagram below:

Image title


A showcase project can be found here.

Spring Framework Spring Boot Dependency

Opinions expressed by DZone contributors are their own.

Related

  • How to Activate New User Accounts by Email
  • Why Camel K?
  • DDD and Spring Boot Multi-Module Maven Project
  • Spring Boot for Microservices: The New Age Framework for Your Apps

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: