Spring - Java配置@Bean参数

时间:2013-12-17 09:45:02

标签: java spring spring-java-config

我刚刚从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个豆有资格成为autowire候选人   这种依赖。依赖注释:   {@ org.springframework.beans.factory.annotation.Qualifier(值= DemoDataSource)}

我有多个DataSource,因此需要@Qualifier。

感谢。

编辑:

这似乎解决了这个问题:

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

...

sessionFactory.setDataSource(dataSourceFactory());

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

1 个答案:

答案 0 :(得分: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;
}