2

我刚刚从 Spring 3.1.1 更新到 3.2.6

对于 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;
}

但是,对于升级版本,我得到以下异常:

原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖找到[javax.sql.DataSource]类型的合格bean:预计至少有1个bean有资格作为此依赖的自动装配候选者。依赖注解:{@org.springframework.beans.factory.annotation.Qualifier(value=DemoDataSource)}

我有多个数据源,因此需要 @Qualifier。

谢谢。

编辑:

似乎这解决了问题:

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

...

sessionFactory.setDataSource(dataSourceFactory());

但是我不认为这是一个很好的解决方案。

4

1 回答 1

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;
}

如果您需要注入数据源,您可能需要切换到使用 aJndiLocatorDelegate来进行查找,而不是使用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;
}
于 2013-12-17T11:22:01.903 回答