简体   繁体   English

Spring-Boot忽略@Qualifier注释

[英]Spring-Boot ignores @Qualifier annotation

I am migrating an active Spring web app to spring boot(1.4.2). 我正在将一个活跃的Spring Web应用程序迁移到spring boot(1.4.2)。

The beans are defined in an XML as it is being loaded with @ImportResource. bean在使用@ImportResource加载时在XML中定义。

4 of the beans that I am starting are an instance of the same object BasicDataSource. 我开始的4个bean是同一个对象BasicDataSource的一个实例。

To tell spring which one to load I have set an ID for each one and using @Qualifier to bind the correct bean to the variable. 要告诉spring哪个加载我已经为每个设置了一个ID并使用@Qualifier将正确的bean绑定到变量。

But it seems to be that Spring ignores my @Qualifier and throwing "No qualifying bean of type 'javax.sql.DataSource' available: expected single matching bean but found 4: DataSource1, DataSource2, DataSource3, DataSource4" 但似乎Spring忽略了我的@Qualifier并抛出“没有类型'javax.sql.DataSource'的限定bean可用:预期的单个匹配bean但找到4:DataSource1,DataSource2,DataSource3,DataSource4”

PS - Note that the class that has the @Qualifier is an abstract class, and the class that is failing to instantiate is an extending class, however @Qualifier has @Inherited. PS - 请注意,具有@Qualifier的类是抽象类,而未能实例化的类是扩展类,但@Qualifier具有@Inherited。

XML XML

<beans
    xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:task="http://www.springframework.org/schema/task"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
   http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/aop 
   http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context-3.2.xsd
   http://www.springframework.org/schema/jee 
   http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
   http://www.springframework.org/schema/task 
   http://www.springframework.org/schema/task/spring-task-3.2.xsd
   http://www.springframework.org/schema/cache
   http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
   http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring
   http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">

<context:load-time-weaver aspectj-weaving="on"/>
<cache:annotation-driven mode="aspectj"/>
<context:property-override location="file:/app/config/dataSourceOverride.cfg"/>
<context:annotation-config />

<bean id="DataSource1" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="userId" value="4" />
</bean>

<bean id="DataSource2" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="userId" value="3" />
</bean>

<bean id="DataSource3" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="userId" value="2" />
</bean>

<bean id="DataSource4" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="userId" value="1" />
</bean>

Spring boot app main Spring启动应用程序主要

package com.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;


@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan("com.app")
@ImportResource("com/app/startup/spring.xml")
public class SpringBootServer {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootServer.class, args);

    }
}

Abstract Class 抽象类

public abstract class GenericDao {

    public GenericDao() {

    }

    private Logger logger = LoggerFactory.getLogger(GenericDao.class);

    @Autowired
    @Qualifier("DataSource1")
    protected BasicDataSource dataSource1Impl;

    @Autowired
    @Qualifier("DataSource2")
    protected BasicDataSource dataSource2Impl;

    @Autowired
    @Qualifier("DataSource3")
    protected BasicDataSource dataSource3Impl;

    @Autowired
    @Qualifier("DataSource4")
    protected BasicDataSource dataSource4Impl;
}

Solid Calss 坚实的Calss

@Component("widgetsDao")
public class WidgetsDao extends GenericDao {

##Some methods##

}

Exception 例外

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

Description:

Field dataSource1Impl in com.app.dal.GenericDao required a single bean, but 4 were found:
    - DataSource1: defined in class path resource [com/app/startup/app-spring.xml]
    - DataSource2: defined in class path resource [com/app/startup/app-spring.xml]
    - DataSource3: defined in class path resource [com/app/startup/app-spring.xml]
    - DataSource4: defined in class path resource [com/app/startup/app-spring.xml]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

What could possibly make spring to ignore my @Qualifier annotation?? 有什么可能让spring忽略我的@Qualifier注释?

Thanks Ahead. 谢谢你。

I was seeing the same error when using multiple data sources, and after making one of the data source beans "primary" the issue seemed to be resolved and I was then able to autowire the correct bean with the @Qualifier annotation. 我在使用多个数据源时看到同样的错误,并且在使一个数据源bean“主要”之后,问题似乎得到了解决,然后我就能够使用@Qualifier注释自动装配正确的bean。

The Spring Boot documentation here agrees with that, saying that when using multiple data sources, one of the data source beans must be primary. 春季启动文档这里与赞同,他说,使用多个数据源时,数据源豆之一必须是首要。

I configured my beans in Java using @Bean annotation, and so I used @Primary annotation to make one primary. 我使用@Bean注释在Java中配置我的bean,因此我使用@Primary注释来创建一个主要注释。 But if you're configuring in XML it looks like the element in XML does have an optional "primary" attribute that could be used if configuring the beans in XML. 但是,如果您在XML中进行配置,则看起来XML中的元素确实具有可选的“主要”属性,如果在XML中配置Bean,则可以使用该属性。

As Jake stated, @Primary annotation should be added at least to get rid of this error. 正如Jake所说,至少应该添加@Primary注释来摆脱这个错误。 Plus: 加:

If you are fetching your datasource properties from an external file, start your primary datasource's properties (ie url, user, pass etc) with spring.datasource in order to override Spring Boot's default inner datasource which is Derby, HSQL or so depending on your configuration. 如果要从外部文件中获取数据源属性,请使用spring.datasource启动主数据源的属性(即url,user,pass等),以覆盖Spring Boot的默认内部数据源,即Derby,HSQL,具体取决于您的配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM