【问题标题】:Inject a Map attribute in a Spring service在 Spring 服务中注入 Map 属性
【发布时间】:2014-04-17 08:56:07
【问题描述】:

[B]我有一个名为 RechercheInfosTableImpl 的类,并注解了 @Component 这个类有一个 Map 类型的属性 我只想通过注释,实例化这个属性并在实例化过程中用类 RechercheInfosTableImpl 的 Spring 注入它。[/B]

这是我的课,但它不起作用(我尝试了很多选择,但它们不起作用,我失去了清醒):

package fr.msa.agora.bp0gos.local.lanceur;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import fr.cnamts.rfos.nomenclature.CodeValeur;
import fr.cnamts.rfos.nomenclature.Table;
import fr.cnamts.rfos.nomenclature.Valeurs;

/**
 * Service de recherche d'informations sur les tables.
 * 
 * 
 */
@Component
public class RechercheInfosTableImpl implements RechercheInfosTable {

    [B]/**
     * Map [clé = "Nom d'une Table" , valeur = "Code Qualifiant associé à cette table"].
     */
    @Resource
    private final Map<String, String> tableauAssociatifNomTableETCodeQualifiantTable;

    /**
     * @param pTableauAssociatifNomTableETCodeQualifiantTable
     */
    @Autowired
    public RechercheInfosTableImpl(final Map<String, String> pMap) {
        tableauAssociatifNomTableETCodeQualifiantTable = pMap;
    }[/B]   

 /**
     * Alimente la Map [clé = "Nom d'une table" , valeur = "Code Qualifiant de cette table"]
     * 
     * @param pNomTable table CNAM lue.
     */
    @Override
    public void extraireInfosTable(final Table pTable) {
        synchronized (tableauAssociatifNomTableETCodeQualifiantTable) {
            // si la table lue n'est pas stockée dans le tableau associatif
            if (!tableauAssociatifNomTableETCodeQualifiantTable.containsKey(pTable.getNom())) {
                boolean valeurTrouvee = false;
                final Iterator<Valeurs> iterateurValeurs = pTable.getValeurs().iterator();
                Valeurs valeurLue;

                // une valeur = une liste de codes

                // parcourir les valeurs de cette map
                // jusqu'à ce qu'on arrive au bout de toutes ces valeurs (ces listes de codes)
                // ou bien qu'on tombe, pour une de ces valeurs, sur un code principal
                while (iterateurValeurs.hasNext() && !valeurTrouvee) {
                    valeurLue = iterateurValeurs.next();
                    // si la liste de codes de la valeur lu n'est pas vide
                    if ((valeurLue != null) && (valeurLue.getCode() != null) && (!valeurLue.getCode().isEmpty())) {
                        final Iterator<CodeValeur> iterateurCodesValeur = valeurLue.getCode().iterator();
                        while (iterateurCodesValeur.hasNext() && !valeurTrouvee) {
                            final CodeValeur codeValeurlue = iterateurCodesValeur.next();
                            // si on trouve pour la valeur lue, un code principal
                            if ((codeValeurlue != null) && ("P".equalsIgnoreCase(codeValeurlue.getR()))
                                    && (!codeValeurlue.getQ().isEmpty())) {
                                // associer, dans le tableur associatif attribut
                                // le nom de la table
                                // et le code qualifiant de cette table
                                tableauAssociatifNomTableETCodeQualifiantTable.put(pTable.getNom(),
                                        codeValeurlue.getQ());
                                valeurTrouvee = true;
                            }
                        }
                    }
                }
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see fr.msa.agora.bp0gos.local.lanceur.RechercheInfosTable#afficherInformations()
     */
    @Override
    public List<String> afficherInformations() {
        final List<String> listeAAfficher = new ArrayList<String>();
        for (final Entry<String, String> element : tableauAssociatifNomTableETCodeQualifiantTable.entrySet()) {
            listeAAfficher.add("Table => Nom : " + element.getKey() + " Code Qualifiant : " + element.getValue());
        }
        return listeAAfficher;
    }
}

还有程序执行过程中出现的错误:

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'lanceurApplicationExtractionDonneesTable' defined in file [D:\platformsg2_R_64\workspace\gos-injecteur-flux-rfos\target\classes\fr\msa\agora\bp0gos\local\lanceur\LanceurApplicationExtractionDonneesTable.class]: Unsatisfied dependency expressed through constructor argument with index 2 of type [fr.msa.agora.bp0gos.local.lanceur.RechercheInfosTable]: : Error creating bean with name 'rechercheInfosTableImpl' defined in file [D:\platformsg2_R_64\workspace\gos-injecteur-flux-rfos\target\classes\fr\msa\agora\bp0gos\local\lanceur\RechercheInfosTableImpl.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.util.Map]: : No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'rechercheInfosTableImpl' defined in file [D:\platformsg2_R_64\workspace\gos-injecteur-flux-rfos\target\classes\fr\msa\agora\bp0gos\local\lanceur\RechercheInfosTableImpl.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.util.Map]: : No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:718)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:194)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:993)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:897)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:574)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at fr.msa.agora.bp0gos.local.lanceur.GestionApplicationStatic.chargementSpring(GestionApplicationStatic.java:36)
    at fr.msa.agora.bp0gos.local.lanceur.LanceurApplicationExtractionDonneesTable.chargerSpring(LanceurApplicationExtractionDonneesTable.java:128)
    at fr.msa.agora.bp0gos.local.lanceur.LanceurApplicationExtractionDonneesTable.main(LanceurApplicationExtractionDonneesTable.java:60)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'rechercheInfosTableImpl' defined in file [D:\platformsg2_R_64\workspace\gos-injecteur-flux-rfos\target\classes\fr\msa\agora\bp0gos\local\lanceur\RechercheInfosTableImpl.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.util.Map]: : No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:718)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:194)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:993)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:897)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:838)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:780)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:697)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:784)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:711)
    ... 15 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:914)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:770)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:697)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:784)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:711)
    ... 29 more

使用 onlys 注释(不修改 XML 文件),如何在我的服务中注入我的 Map 属性? 事实上,有人要求我只使用注释。

如果我删除带有@Autowired注解的构造函数,即使编译也不起作用。

提前致谢, 托马斯

【问题讨论】:

    标签: spring


    【解决方案1】:

    我不知道你想从你的代码中做什么。但是在春季注入Map 需要Map&lt;String, Class&lt;?&gt;&gt; 签名。类必须是 interface。然后 Spring 会自动将每个 impl 类及其分配的 bean 名称连接到该映射中。

    目前您正在尝试注入String,这是不可能的,因为字符串不是弹簧管理的对象。

    或者,如果我误解了你,而你真的想注入 Map&lt;String, String&gt;:创建一个包装类来保存你想要注入的地图,例如:

    @Component
    class MapWrapper {
        private Map<String, String> map;
    }
    

    【讨论】:

    • 非常感谢membersound。有用。就像你说的,我创建了一个带有 Map 属性 (Map) 的包装器,我使用这个包装器来访问这个地图,并将日期存储在这个地图中。
    • 我想将您的答案标记为有用,但我不能,因为我的声誉未满 15 岁。
    【解决方案2】:

    尝试在 @Resource 注释之外使用 @Qualifier("[name of map]")

    Spring 有时会遇到具体类型的问题。就我而言,我需要创建一个 HashMap 类型的设置器,以便注入工作正常。

    【讨论】:

    • 谢谢马库斯。我会试试。我让你知道。
    • 我以这种方式尝试:我将属性 HashMap 的类型放入其中,并将@Qualifier 注释和没有注释的设置器关联到它。但它不起作用。我忘记了什么吗?请让我知道马库斯。谢谢,
    • 你会发布你的 bean 定义吗?是否尝试使用自传?
    • 谢谢马库斯。事实上,我创建了一个带有 Map 属性 (Map) 的包装器,我使用这个包装器来访问这个地图,并将日期存储在这个地图中。
    • Markus,我想将您的答案标记为有用,但我不能,因为我的声誉未满 15 岁。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 2016-05-17
    • 2014-02-21
    相关资源
    最近更新 更多