spring-boot 1.4.1 dependency injection difference between @Resource and @Autowired

339 Views Asked by At

I have a spring boot bean which is a proxy object for a dynamic data-source object.

@Bean("schemaSwappableDataSource")
public ProxyFactoryBean schemaSwappableDataSource(@Autowired @Qualifier("schemaSwappableDataSourceProxy") SchemaSwappableDataSourceProxy schemaSwappableDataSourceProxy){
    try {
        ProxyFactoryBean bean = new ProxyFactoryBean();
        Class<?>[] classList = {javax.sql.DataSource.class};
        bean.setProxyInterfaces(classList);
        bean.setTargetSource(schemaSwappableDataSourceProxy);
        //return (DataSource)bean.getObject();
        return bean;
    }catch(Exception e){
        e.printStackTrace();
        return null;
    }
}

When I try to inject this bean using @Autowired I get below error at runtime.

@Autowired
@Qualifier("schemaSwappableDataSource")
DataSource schemaSwappableDataSource;

Eroor message

11:39:24.238 - WARN  - [SpringApplicationRunListeners.java:91] - Error handling failed (Error creating bean with name 'delegatingApplicationListener' defined in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor]: Factory method 'transactionAdvisor' threw exception; nested exception is java.lang.NullPointerException)
11:39:24.410 - ERROR - [LoggingFailureAnalysisReporter.java:42] - 

***************************
APPLICATION FAILED TO START
***************************

Description:

Field schemaSwappableDataSource in com.siemens.rcs.dc.comment.dao.impl.CommentDAOImpl required a bean of type 'javax.sql.DataSource' that could not be found.
    - Bean method 'dataSource' not loaded because @ConditionalOnProperty (spring.datasource.type) did not find property 'spring.datasource.type'
    - Bean method 'dataSource' not loaded because @ConditionalOnProperty (spring.datasource.jndi-name) did not find property 'jndi-name'
    - Bean method 'dataSource' not loaded because @ConditionalOnClass did not find required class 'javax.transaction.TransactionManager'


Action:

Consider revisiting the conditions above or defining a bean of type 'javax.sql.DataSource' in your configuration.

But if I use

@Resource(name="schemaSwappableDataSource")
DataSource schemaSwappableDataSource;

It works fine…. Can anyone tell me what I am doing wrong and what could be a better way to use ProxyFactory bean in this kind of scenario? I need to create data source objects at runtime because the data source dynamically needs to connect to different type of databases based on parameters passed. It does not need to create new data source every time, because once created it is stored in static map and fetches them based on thread-local variable. Any help, best practices please advice.

1

There are 1 best solutions below

0
On BEST ANSWER

Thanks All, it worked with a simple cust.

@Bean("schemaSwappableDataSource")
public DataSource schemaSwappableDataSource(@Autowired @Qualifier("schemaSwappableDataSourceProxy") SchemaSwappableDataSourceProxy schemaSwappableDataSourceProxy) throws ClassNotFoundException{
        ProxyFactoryBean bean = new ProxyFactoryBean();
        Class<?>[] classList = {javax.sql.DataSource.class};
        bean.setProxyInterfaces(classList);
        bean.setTargetSource(schemaSwappableDataSourceProxy);
        return javax.sql.DataSource.class.cast(bean.getObject());
}

@Bean("schemaSwappableJdbcTemplate")
public JdbcTemplate schemaSwappableJdbcTemplate(@Qualifier("schemaSwappableDataSource") DataSource schemaSwappableDataSource) {
    return new JdbcTemplate(schemaSwappableDataSource);
}

@Bean("schemaSwappableTxManager")
public DataSourceTransactionManager schemaSwappableTxManager(@Qualifier("schemaSwappableDataSource") DataSource schemaSwappableDataSource){
    DataSourceTransactionManager txMgr = new DataSourceTransactionManager();
    txMgr.setDataSource(schemaSwappableDataSource);
    return txMgr;
}

had some trouble with combining two annotations the custom one @SchemaSelector <- custom & @Transactional <-- provided by spring. But able to resolve that by using org.springframework.core.Ordered interface.