Jonatan Mendoza
Jonatan Mendoza

Reputation: 93

Why adding @Bean to a method I'll call directly

I have seen lots of examples about Spring configuration through @Configuration and @Bean annotations. But I relealized that it's a common practice to add @Bean annotation to methods that are called directly to populate other beans. For example:

@Bean
public Properties hibernateProperties() {
    Properties hibernateProp = new Properties();
    hibernateProp.put("hibernate.dialect",
            "org.hibernate.dialect.H2Dialect");
    hibernateProp.put("hibernate.hbm2ddl.auto", "create-drop");
    hibernateProp.put("hibernate.format_sql", true);
    hibernateProp.put("hibernate.use_sql_comments", true);
    hibernateProp.put("hibernate.show_sql", true);
    return hibernateProp;
}

@Bean public SessionFactory sessionFactory() {
    return new LocalSessionFactoryBuilder(dataSource())
            .scanPackages("com.ps.ents")
            .addProperties(hibernateProperties())
            .buildSessionFactory();}

So, I'm wondering if it's better just declaring the hibernateProperties() as private without the @Bean annotation.

I would like to know if this is a bad/unneeded common practice or there is a reason behind.

Thanks in advance!

Upvotes: 1

Views: 4947

Answers (2)

Evgeni Dimitrov
Evgeni Dimitrov

Reputation: 22506

Decorating a method in @Configuration class with @Bean means that the return value of that method will become a Spring bean.

By default those beans are singletons(only one instance for the lifespan of the application).

In your example Spring knows that hibernateProperties() is a singleton bean and will create it only ones. So here:

@Bean public SessionFactory sessionFactory() {
    return new LocalSessionFactoryBuilder(dataSource())
            .scanPackages("com.ps.ents")
            .addProperties(hibernateProperties())
            .buildSessionFactory();
}

hibernateProperties() method will not be executed again, but the bean will be taken from the application context. If you don't annotate hibernateProperties() with @Bean it will be a simple java method and it will be executed whenever it's called. It depends on what you want.

Just to mention, the other way to do dependency injection in @Configuration classes is add a parameter. Like this:

@Bean public SessionFactory sessionFactory(Properties props) {
        return new LocalSessionFactoryBuilder(dataSource())
                .scanPackages("com.ps.ents")
                .addProperties(props)
                .buildSessionFactory();
    }

When Spring tries to create the sessionFactory() bean it will first look in the application context for a bean of type Properties.

Upvotes: 1

Daniel C.
Daniel C.

Reputation: 5758

According to Spring Documentation inter-bean dependency injection is one good approach in order to define the bean dependencies in a simple form. Of course if you define your hibernateProperties() as private it will work but it could not be injected to other components in your application through Spring Container.

Just decide depending on how many classes depends on your bean and also if you need to reuse it in order to call its methods or inject it to other classes.

Upvotes: 1

Related Questions