Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

254
Views
Spring Bean Dependency Does not Decide Construct Order

When doing debugging with break points, I noticed that the order of execution of the @Bean annotated methods is not really related to their dependency relation. For e.g:

@Configuration
public class config {

    @Bean (name = "myDataSource")
    public DataSource dataSource() {return new HikariDataSource();}


    @Bean
    public TransactionManager transactionManager(@Qualifier("myDataSource") DataSource dataSource) {
        return new TransactionManager(dataSource);
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {...}
}

The transactionManager or sqlSessionFactory method always gets run before the dataSource() method in my app. I made sure there's no data source auto config or any other code that might have created another data source.

And the app behavior is correct, it can connect to the correct DB and retrieve data.

This odd behavior might have something to do with multiple datasources. I configured more than 1 datasource in my app.

I know Spring has similar mechanism when dealing with cyclic dependencies. Say class A and B depends on each other, and when creating Bean A, A.b will be set to an empty instance of B. The same goes for B.

Here I'm assuming when running method sqlSessionFactory(), an empty dataSource will be created and passed to it. And that dataSource will later reference/proxy bean "myDataSource".

I want to know if my assumption is correct or if someone can explain the behavior clearly.

Edit

This is what my debug point looks like: enter image description here

So the transactionManager() method always gets run first. And at this time, the injected dataSource (HikariDataSource) is still null.

But after the app starts and makes DB queries, it's using the correct dataSource:

enter image description here

My another dataSource is called orderDataSource and the mapper is referring it correctly.

I mean at last the transactionManger and sqlSessionFactory do use my specified dataSources, satisfying what my annotation demands, otherwise it would be a Spring bug and the app won't be able to function. But when the main thread is initializing those beans, the dataSource() method gets run last. I find it out in debugging mode. I'm trying to understand the underlying mechanism here.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

If you want to specify a specific order, then you can use @DependsOn

We should use this annotation for specifying bean dependencies. Spring guarantees that the defined beans will be initialized before attempting an initialization of the current bean.

If you want myDataSource to be initialized first, define @DependsOn({"myDataSource"})

@DependsOn({"myDataSource"})
@Bean
public TransactionManager transactionManager(@Qualifier("myDataSource") DataSource dataSource) {
    return new TransactionManager(dataSource);
}

@DependsOn({"myDataSource"})
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {...}

Beans on which the current bean depends. Any beans specified are guaranteed to be created by the container before this bean

over 4 years ago · Santiago Trujillo Report

0

Here I'm assuming when running method sqlSessionFactory(), an empty dataSource will be created and passed to it. And that dataSource will later reference/proxy bean "myDataSource". I want to know if my assumption is correct or if someone can explain the behavior clearly.

In order to answer this question we need to look into the bean creation lifecycle

enter image description here

Note that instantiation happens first, waaaaaay before everything else. This is where the @Bean annotated methods run.

Now its important to realise that Spring not always injects your dependencies directly, instead it can injects proxies, which wrap your beans. This is necessary to make some of Springs magic like AOP to work.

To see precisely what is being injected into your @Bean methods you can just set a debug breakpoint at these methods. Just using toString() won't work ... it will just tell you that its an ordinary object (proxy tries to hide that it's there lol ... )

If you investigate with the debugger, however ... you will see this ...

enter image description here

See ? There is no instance of object A being injected. A proxy is injected.

So, Spring does this in your case ... it creates these beans with @Bean methods and just gives each one a proxy of the dependency. Afterwards, since Spring has references to all the beans and proxies ... it wires them up together by figuring out the dependency graph via an algorithm similar to topological sort.

If something is still unclear, please leave a comment and I'll expand on it.

It would also help, if you could look in the debugger in the example above to see exactly what is being injected into your methods in place of the DataSource bean in both cases.

This will enable us to precisely pinpoint what's going on.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!