2013-12-17 2 views
2

Я только что обновил с весны 3.1.1 до 3.2.6Spring - конфигурация Java @Bean параметр

С 3.1 следующий код работал хорошо:

@Bean(name = DEMO_DS) 
public JndiObjectFactoryBean demoDataSource() 
{ 
    JndiObjectFactoryBean factory = new JndiObjectFactoryBean(); 
    factory.setJndiName(JDBC_DEMO_DS); 
    factory.setProxyInterface(DataSource.class); 
    return factory; 
} 

@Bean(name = DEMO_SESSION_FACTORY) 
public SqlSessionFactoryBean demoSqlSessionFactory(@Qualifier(DEMO_DS) DataSource dataSource) 
{ 
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); 
    sessionFactory.setDataSource(dataSource); 
    sessionFactory.setConfigLocation(new ClassPathResource("demo/config.xml")); 

    return sessionFactory; 
} 

Однако с uprgraded версии я получаю следующее исключение:

Вызванное: org.springframework.beans.factory.NoSuchBeanDefinitionException: Нет квалификационных рожкового типа [javax.sql.DataSource] найдено для отда endance: ожидается как минимум 1 бит, который квалифицируется как кандидат на автоподбор для этой зависимости. Зависимость от аннотаций: {@ org.springframework.beans.factory.annotation.Qualifier (значение = DemoDataSource)}

У меня есть несколько DataSources поэтому @Qualifier необходимость.

Спасибо.

Edit:

кажется, что это решает проблему:

public DataSource dataSourceFactory() { 
    try 
    { 
     return (DataSource) demoDataSource().getObject(); 
    } 
    catch (Exception ex) 
    { 
     throw new RuntimeException(ex); 
    } 
} 

... 

sessionFactory.setDataSource(dataSourceFactory()); 

Однако я не думаю, что это хорошее решение.

ответ

0

В зависимости от вашей потребности перепишите конфигурацию немного. Если вам действительно не нужен ввод данных, вы можете сделать что-то подобное.

@Bean(name = DEMO_DS) 
public JndiObjectFactoryBean demoDataSource() { 
    JndiObjectFactoryBean factory = new JndiObjectFactoryBean(); 
    factory.setJndiName(JDBC_DEMO_DS); 
    factory.setProxyInterface(DataSource.class); 
    return factory; 
} 

@Bean(name = DEMO_SESSION_FACTORY) 
public SqlSessionFactoryBean demoSqlSessionFactory() { 
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); 
    sessionFactory.setDataSource(demoDataSource().getObject()); 
    sessionFactory.setConfigLocation(new ClassPathResource("demo/config.xml")); 
    return sessionFactory; 
} 

Если вам необходимо иметь источник данных впрыскивается вы можете перейти к использованию JndiLocatorDelegate, чтобы сделать поиск вместо JndiObjectFactoryBean.

@Bean(name = DEMO_DS) 
public DataSource demoDataSource() throws NamingException { 
    return JndiLocatorDelegate.createDefaultResourceRefLocator().lookup(JDBC_DEMO_DS, DataSource.class); 
} 

Это дает вам DataSource непосредственно вместо FactoryBean<Object> (который является то, что JndiObjctFactoryBean есть), что, вероятно, является источником проблемы.

Или (теоретически) вы также можете использовать аннотацию @Value для свойства в вашем конфигурационном классе. Вместо @Value нормальный @Resource также должен делать трюк (который также может делегировать вызов JNDI для поиска).

public class MyConfig { 

    @Value("${" + JDBC_DEMO_DS + "}") 
    private DataSource demoDs; 

} 

С @Resource

public class MyConfig { 

    @Resource(mappedName=JDBC_DEMO_DS) 
    private DataSource demoDs; 

} 

И вы можете просто ссылаться на него в методе конфигурации.

@Bean(name = DEMO_SESSION_FACTORY) 
public SqlSessionFactoryBean demoSqlSessionFactory() { 
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); 
    sessionFactory.setDataSource(demoDs); 
    sessionFactory.setConfigLocation(new ClassPathResource("demo/config.xml")); 
    return sessionFactory; 
} 
Смежные вопросы