2

I work on a project witch contains two dataSources. If I want to inject the securityDataSource, spring injects the defaultDataSource instead.

applicationContext.xml :

<bean id="defaultDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName">
        <value>${default.jndi.datasource.name}</value>
    </property>
</bean>

<bean id="securityDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName">
        <value>${security.jndi.datasource.name}</value>
    </property>
</bean>

setter :

@Required
@Resource
public void setSecurityDataSource(DataSource securityDataSource) {
    jdbcTemplate = new JdbcTemplate(securityDataSource);
}

The server logs this (which apparently isn't blocking anything though) for both security and default datasource:

10:28:23.912 [INFO ] o.s.w.c.s.XmlWebApplicationContext - Bean 'defaultDataSource' of type [class org.springframework.jndi.JndiObjectFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
10:28:24.345 [INFO ] o.s.w.c.s.XmlWebApplicationContext - Bean 'defaultDataSource' of type [class org.apache.commons.dbcp.BasicDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
10:28:24.922 [INFO ] o.s.w.c.s.XmlWebApplicationContext - Bean 'securityDataSource' of type [class org.springframework.jndi.JndiObjectFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
10:28:25.444 [INFO ] o.s.w.c.s.XmlWebApplicationContext - Bean 'securityDataSource' of type [class org.apache.commons.dbcp.BasicDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

No stacktrace is shown anywhere in the code.

When I try :

private SecurityUserDTO retrieve(String userLogin) {
    return jdbcTemplate.query("SELECT * FROM users WHERE username = ?", with(userLogin), new UserExtractor());
}

Hibernate wont find the table users stored in database security, because it looks for it in the default database (which doesn't have such a table)

HTTP Status 401 - PreparedStatementCallback; bad SQL grammar [SELECT * FROM users WHERE username = ?]; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'condor.users' doesn't exist

if I try injecting and providing the name securityDataSource:

@Required
@Resource(name="securityDataSource")
public void setSecurityDataSource(DataSource securityDataSource) {
    jdbcTemplate = new JdbcTemplate(securityDataSource);
}

I will get a stackTrace :

12:17:48.557 [ERROR] o.s.w.c.ContextLoader - Context initialization failed
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'securityDataSource' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:529) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:277) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:442) ~[spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416) ~[spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:549) ~[spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:159) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) ~[spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303) ~[spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE]
Wrapped by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'accountService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'securityDataSource' is defined

However, the bean securityDataSource exists indeed, and was instanciated by spring in the context.

help me please, thanks !

4

1 回答 1

0

实际上,我的 defaultDataSource bean 是在 applicationContext.xml 中声明的,而我的 securityDataSource bean 是在 applicationContext-security.xml 中,尽管 contextConfigLocation 没有声明要在 web.xml 中浏览。以下是更改的示例代码:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

至:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml, /WEB-INF/applicationContext-security.xml</param-value>
</context-param>

它有效!我看到的 securityDataSource bean 属于另一个上下文......

于 2013-07-17T13:13:27.393 回答