Spring Boot Weblogic 12c JNDI DataSources: injecti

2019-07-30 08:28发布

I had asked a question here but was incomplete and was marked as duplicate here

So based on the question already asked - one particular answer by @surasin-tancharoen seemed to be what I needed.

However trying that too gives me a NullPointerException since the data source is never created / injected.

Here are the details:

In the below code I have defined 2 beans. I have defined both datasources with @Qualifier annotation and @ConfigurationProperties to read the JNDI name from properties file.

@Configuration
public class DataSourceConfig {
    @Bean
    @Primary
    @Qualifier("ds1")
    @ConfigurationProperties(prefix="spring.datasource1")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Qualifier("ds2")
    @ConfigurationProperties(prefix="spring.datasource2")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }
}

In application.properties:

spring.datasource1.jndi-name=AbcDS
spring.datasource2.jndi-name=XyzDS

Then in my DAO - I am trying to use this datasource:

@Autowired
@Qualifier("ds1")
DataSource dataSource;

However the datasource is not injected since I get a NullPointerException at this line of code:

conn = dataSource.getConnection();

All of this is being attempted by deploying the Spring Boot application to Weblogic 12c

1条回答
叛逆
2楼-- · 2019-07-30 09:05

The solution is related to incorrect usage of 'DataSourceBuilder' which should not be used for a JNDI datasource.

Here is how I got it working : ( deploying spring boot war on weblogic and consuming datasources defined in weblogic )

First we specify the datasources defined in weblogic - here we specify the JNDI name of the datasources defined in weblogic:

spring.datasource.xyz.jndi-name=XYZDS
spring.datasource.test.jndi-name=TESTDS

This is where the Datasource is created using above defined properties and exposed: We are injecting the properties from application.properties into string variables to store JNDI names of datasources.

@Configuration
public class DataSourceConfig {

@Value( "${spring.datasource.xyz.jndi-name}" )
private String xyzJndiName;

@Value( "${spring.datasource.test.jndi-name}" )
private String testJndiName;

@Bean(name = "XyzDataSource")
public DataSource getXyzDataSource() throws Exception {        
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    return dataSourceLookup.getDataSource(xyzJndiName);
}   

@Bean(name = "TestDataSource")
public DataSource getTestDataSource() throws Exception {        
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    return dataSourceLookup.getDataSource(testJndiName);
}  

A few key points to note : We should not be using 'DataSourceBuilder' for a JNDI datasource - it will not work.

This was the reason why it was not working in my case .

Now I am using 'JndiDataSourceLookup' which does the trick.

Another thing to note is that we need to use the standard @Bean annotation with the attribute 'name'.

This will be important in the piece of code that consumes this datasource. So now the datasources are created successfully and exposed.

OK time to consume :

@Repository
public class SomeDaoImpl {

@Autowired
@Qualifier("XyzDataSource")
DataSource dataSource;

@Override
public List <String> create(Employee request) {

    Connection conn = null;
    conn = dataSource.getConnection();

Here we are using the @Qualifier annotation to pickup the appropriate datasource . Thats it - this works now. I tried it with the other data source - it worked as well.

NOTE: I would not like to accept my own answer - so I will wait for a couple of days if anyone else has a better and more elegant solution please answer - will be happy to accept your answer rather than answering my own question and accepting !

查看更多
登录 后发表回答