Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

260
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda