Search code examples
springspring-transactions

Spring transaction configruation (bean vs inner class)


In examples from book Spring in action I found that configuration of TransactionManager is achieved by nested class:

@Configuration
@ComponentScan
public class JpaConfig {

//EntityManagerFactory, JpaVendorAdapter, DataSource @Beans

  @Configuration
  @EnableTransactionManagement
  public static class TransactionConfig implements TransactionManagementConfigurer {
    @Inject
    private EntityManagerFactory emf;

    public PlatformTransactionManager annotationDrivenTransactionManager() {
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(emf);
      return transactionManager;
    }    
  }
}

Is it a good practice or something? Is there any difference in comparison to standard @Bean approach like:

@Configuration
@EnableTransactionManagement
public class DbConfig {

//EntityManagerFactory, JpaVendorAdapter, DataSource @Beans

    @Bean
    public JpaTransactionManager createTransactionManager(EntityManagerFactory emf) {
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        jpaTransactionManager.setEntityManagerFactory(emf);
        return jpaTransactionManager;
    }

}

or it is just about separating responsibilities?


Solution

  • Is it a good practice or something? Is there any difference in comparison to standard @Bean

    Both the approaches work as you might have already noticed.

    The first approach is similar to inner bean concept.

    If you know that the bean is not going to be used by any other bean except the outer bean then you can declare it as an inner bean. The advantage here is that by making the bean as inner bean you are ensuring that it is not exposed to the other beans except the outer bean and so won't be able to use/inject the inner bean in other beans.

    Quoting from the above link

    An inner bean definition does not require a defined id or name; if specified, the container does not use such a value as an identifier. The container also ignores the scope flag on creation: Inner beans are always anonymous and they are always created with the outer bean. It is not possible to inject inner beans into collaborating beans other than into the enclosing bean or to access them independently.