javaspringspring-java-config

how to convert jndi lookup from xml to java config


Currently I'm converting the xml to java config. But I stuck at some part that I have been research for several days. Here the problem:

Xml config:

     <jee:jndi-lookup id="dbDataSource" jndi-name="${db.jndi}" resource-ref="true" />

     <beans:bean id="jdbcTemplate"
     class="org.springframework.jdbc.core.JdbcTemplate" >
     <beans:property name="dataSource" ref="dbDataSource"></beans:property>
     </beans:bean>

So far I managed to convert this code:

<jee:jndi-lookup id="dbDataSource" jndi-name="${db.jndi}" resource-ref="true" />

to this :

@Bean(name = "dbDataSource")
public JndiObjectFactoryBean dataSource() {
   JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
   bean.setJndiName("${db.jndi}");
   bean.setResourceRef(true); 
   return bean; 
}

And this :

     <beans:bean id="jdbcTemplate"
     class="org.springframework.jdbc.core.JdbcTemplate" >
     <beans:property name="dataSource" ref="dbDataSource"></beans:property>
     </beans:bean>

to this:

@Bean(name = "jdbcTemplate")
public JdbcTemplate jdbcTemplate() { 
   JdbcTemplate jt = new JdbcTemplate();
    jt.setDataSource(dataSource);
    return jt;
   }

The problem is the method setDataSource() need DataSource object but I'm not sure how to relate both bean.How to pass the JndiObjectFactoryBean to DataSource?

Or do I need to use another method?

Extra Question:

The bean.setJndiName("${db.jndi}") , ${db.jndi} is refer to properties file but I always got NameNotFoundException, How to make it work?

Thanks!!


Solution

  • Instead of JndiObjectFactoryBean use a JndiDataSourceLookup instead. To use the ${db.jndi} in the method declare a method argument and annotate it with @Value.

    @Bean(name = "dbDataSource")
    public DataSource dataSource(@Value("${db.jndi}") String jndiName) {
        JndiDataSourceLookup lookup = new JndiDataSourceLookup();
        return lookup.getDataSource(jndiName);
    }
    

    Autowired methods and constructors can also use the @Value annotation. -- Spring Reference Guide.

    @Bean methods are basically factory methods which are also auto wired methods and as such fall into this category.

    In your factory method for the JdbcTemplate you can simply use a DataSource method argument to get a reference to the datasource (If you have multiple you can use the @Qualifier on the method argument to specify which one you want to use).

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource ds) { 
        return new JdbcTemplate(ds);
    }