0

In my Spring Configuration class , I need jdbcTemplate to initialize other bean.

@Configuration
public class ApplicationBeansConfiguration {
    @Bean
    public JdbcTemplate jdbcTemplate() throws GeneralSecurityException {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
        return jdbcTemplate;
    }

    @Bean
    @Lazy 
    public Map<String, String> someDatabaseTableValues(){
    // I need jdbcTemplate bean here.

}
2
  • 3
    Just add it as a method argument someDatabaseTableValues(JdbcTemplate template).
    – M. Deinum
    Commented Jan 21, 2016 at 14:48
  • use @DependsOn("jdbcTemplate") instead of @Lazy and invoke JdbcTemplate jdbcTemplate = jdbcTemplate(); ... inside your someDatabaseTableValues() method. The first annotation gurantees that the jdbcTemplate bean is initialized before someDatabaseTableValues() is being initialized. Skipping @DependsOn may result in a circular reference exception. In addition to that, it's always safe to name your beans, i.e. @Bean(name = "jdbcTemplate") ... Commented Jan 21, 2016 at 15:58

1 Answer 1

1

Use it like this:

@Bean
@Lazy 
public Map<String, String> someDatabaseTableValues() {
    //the following JdbcTemplate instance will already be configured by Spring
    JdbcTemplate template = jdbcTemplate();
    ...
}

Some explanation: Spring needs CGLIB for @Configuration class processing. It effectively makes a CGLIB proxy out of your configuration classes. When you invoke a @Bean method on your configuration class, it will be handled by the CGLIB proxy. The proxy interceptor will check if an already configured instance of the bean is readily available (for singleton beans) and return that cached instance. If there's no cached instance, it will invoke your @Bean factory method and apply any configuration and bean postprocessing your application context is set up to do. When it returns it will cache the bean instance if needed (again, in case of singleton beans) and return the configured bean instance to you.

You can also use method-injection with @Autowired:

@Autowired
@Bean
@Lazy 
public Map<String, String> someDatabaseTableValues(JdbcTemplate template) {
    ...
}

You can use @Qualifier() annotation in front of your autowired method parameters do distinguish between multiple instances of the same bean type.

Note that you could also use JSR-250's @Resource or JSR-330's @Inject annotations instead of @Autowired, as those are supported as well by Spring.

Not the answer you're looking for? Browse other questions tagged or ask your own question.